# This block of code will create a blank SPI dataset (only containing country info) that will be appended to when each indicator is added.
# There will be two indicators added for each dimension
# 1. An indicator with a score between 0-1 for each dimension
# 2. An indicator with the raw (unscored) values of the indicators
# The unit for this database will be country*year

span <- c(2004:2019)

spi_df_empty <- bind_rows(replicate(length(span), wbstats::wbcountries(), simplify = FALSE), .id='date') %>%
  mutate(date=as.numeric(date)+span[1]-1) %>%
  filter(region!="Aggregates") # take out the aggregates (LAC, SAR, etc)

spi_df <- spi_df_empty

#read list of iso3c codes for matching from UN (https://unstats.un.org/unsd/methodology/m49/)
iso3c <- read_csv(paste(raw_dir,'metadata/iso_codes.csv', sep="/"),
                  col_types=list(col_character(), col_character(), col_character()))

Introduction

In this program, I will clean and reshape the raw data files in the 01_rawdata folder in order to produce the Statistical Performance Indicators.

Below is an overview of the SPI framework.

unchanged image # Handling missing data

It is likely that for the initial launch of the Dashboard there will be several types of missing data.

In the absence of any new data, the existing material collected for the Statistical Performance Index could be used to populate an initial dashboard as follows:

• Data use dimension: leave blank

• Data services dimension: use scores for SPI “dissemination practices and openness” dimension

• Data products dimension: use scores for SPI “availability of key indicators” dimension

• Data sources dimension: use scores for SPI “censuses and surveys” dimension

• Data infrastructure dimension: use scores for SPI “methodology, standard and classifications” dimension

Indeed, a first iteration Dashboard and toolkit can be demonstrated using this existing data. As new methods are developed and data are collected, the Dashboard can progressively be populated. Where it has not been possible to develop and implement a methodology for the dashboard tile concerned, this should be left blank to signify that this is an important issue that has not yet been quantified in a way that meets the criteria for the Dashboard. This will provide an incentive for a research agenda and possibly surveys and other mechanisms to fill the gap for a particular purpose eg a country assessment.

Where it has been possible to develop and implement a methodology but it has not been possible to find data for a specific country, even though it is known to exist, the Dashboard tile for that country should also be left blank and weighting between tiles conducted on the basis of the tiles that are present.

In some situations, missing data represents a zero score, for example if there is no evidence that geospatial data is used by the country’s statistical system. In such cases a score of zero should be recorded and used in the generation of indicators, weightings and rankings.

Data Use

Cleaning for Data Use Indicators. Data Use (5 Indicators):
- 1.1_DUNL - Indicator 1.1: Data use by national legislature
- 1.2_DUNE - Indicator 1.2: Data use by national executive branch
- 1.3_DUCS - Indicator 1.3: Data use by civil society
- 1.4_DUAC - Indicator 1.4: Data use by academia
- 1.5_DUIO - Indicator 1.5: Data use by international organizations

Indicator 1.1: Data use by national legislature

Based on PARIS21 data use indicator (Chapter 4 of Statistical Capacity Development Outlook) using national legislature website as source.

Indicator 1.2: Data use by national executive branch

Based on PARIS21 data use indicator (Chapter 4 of Statistical Capacity Development Outlook) using voluntary national review plans as a source.

Our main source for this is the UN Voluntary National Reviews (VNR) Database (https://sustainabledevelopment.un.org/vnrs/).

The indicator for each data use by the national executive branch is formed by:
1. Searches the documents for references to a set of keywords related to each SDG goal
2. Searches the documents for the subset of references that also include statistics, by searching for numeric values (excluding references to years)
3. Calculates the ratio between the two

The ratio captures density of discussion of each topic in each document assessed. The keywords are based on indicators found in the World Bank’s World Development Indicators (WDI).

#load data
vnr_use_df <- read_csv(paste(raw_dir, "/1.2_DUNE/UN_VNR_use_of_numbers.csv", sep="")) %>%
  group_by(country) %>%
  filter(year==max(year, na.rm=T)) %>%
  mutate(date=2019)


vnr_use_merge <- vnr_use_df %>% 
  group_by(country, date, name) %>%
  summarise(SPI.D1.2.VNR=wtd.mean(freq_of_numbers, w=freq_of_terms))


#add to spi databases
spi_df <- spi_df %>%
  left_join(vnr_use_merge)

#map the VNR data

#overall score
spi_mapper('vnr_use_merge', 'SPI.D1.2.VNR', 'Overall Score for Use of Numbers in VNRs')

# #SDG 1
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 1") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 1')
# 
# #SDG 2
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 2") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 2')
# 
# #SDG 3
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 3") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 3')
# 
# #SDG 4
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 4") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 4')
# 
# #SDG 5
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 5") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 5')
# 
# #SDG 6
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 6") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 6')
# 
# #SDG 7
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 7") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 7')
# 
# #SDG 8
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 8") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 8')
# 
# #SDG 9
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 9") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 9')
# 
# #SDG 10
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 10") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 10')
# 
# #SDG 11
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 11") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 11')
# 
# #SDG 12
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 12") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 12')
# 
# #SDG 13
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 13") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 13')
# 
# #SDG 14
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 14") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 14')
# 
# #SDG 15
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 15") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 15')
# 
# #SDG 16
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 16") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 16')
# 
# #SDG 17
# vnr_map <- vnr_use_df %>%
#   filter(SDG=="SDG 17") 
# 
# spi_mapper('vnr_map', 'freq_of_numbers', 'Use of Numbers in VNRs for SDG 17')

Indicator 1.3: Data use by civil society

Based on PARIS21 data use indicator (Chapter 4 of Statistical Capacity Development Outlook) using main social media platform in use in country as source.

We are pulling data from Twitter at this point. We have only accessed a handful of accounts from NSOs, but this could be quickly scaled up.

Indicator 1.4: Data use by academia

The idea for this indicator is that countries should be producing statistical products that are utilized, in this case by academia. As a measure of this, we use the IHSN database on censuses and surveys conducted by counties and calculate a ranking of countries based on the total number of downloads of the censuses and surveys produced by that country on a per capita basis. In other words, we calculate the total number of downloads of censuses and surveys for a country, divided by the population of that country, to produce a ranking. Countries with low scores on this metric, may either be producing censuses and surveys that are not in high demand or are not producing or adding a sufficient number of censuses and surveys to IHSN to register highly on this measure.

The source for this indicator is the IHSN.

The mission of the IHSN is to improve the availability, accessibility, and quality of survey data within developing countries, and to encourage the analysis and use of this data by national and international development decision makers, the research community, and other stakeholders.

To support this mission, the key objectives of the IHSN are:

Improved coordination of internationally sponsored survey programs, with emphasis on timing, sequencing, frequency, and cost-effectiveness Availability of coordinated and practical technical and methodological guidelines for all stages of the survey life cycle Availability of a central survey data catalog which would inform data users of the availability of survey and census data from multiple sources Availability of standards, tools, and guidelines that would allow data producers to document, disseminate, and preserve microdata according to international standards and best practices Improved collaboration between data producers and users

IHSN has a database of more than 7,483 surveys as of August 5, 2020.

Indicator 1.5: Data use by international organizations

The following indicator will measure how useful data sources produced in national statistics systems are for international organizations. We gather three measures of how useful or reliable country produced measures are for international organizations. The first on comparability of poverty estimates for the World Bank reporting on international poverty. A second on statistics on child mortality for the UN Inter-agency Group for Child Mortality Estimation. A third on accuracy of debt reporting as classified by the World Bank. Each of these will be described in greater detail below.

While these three indicators are not comprehensive of all statistics produced by countries, they do provide some indication of whether countries are producing estimates that are useful to international organizations for their reporting and monitoring efforts.

Poverty Comparability

The first measure examines whether comparable poverty estimates are produced by countries over time. The World Bank’s Povcalnet has introduced a comparability indicator for whether the country produces comparable poverty estimates over time. https://blogs.worldbank.org/opendata/apples-apples-povcalnet-introduces-new-comparability-indicator. This metadata has been compiled by the Country Poverty Economists in the World Bank’s Poverty and Equity Global Practice. From the Povcalnet team:

As countries frequently improve household surveys and measurement methodologies, strict comparability of poverty estimates over time is often limited. Strictly comparable poverty estimates within a country require a consistent production process, including the sampling frame, questionnaires, the methodological construction of the welfare aggregates and poverty lines, a consistent deflation of prices in time and space, among many  other considerations. Thus, the assessment of comparability is country-dependent and relies on the knowledge of the Country Poverty Economist and Regional Poverty Teams of the Poverty Global Practice, as well as close  dialogue with national data producers with intimate knowledge of the survey design and methodology. Within a country, we assume comparability of poverty estimates over time unless there is a known change to survey     methodology, measurement or data structure. More details on the comparability metadata database can be found in Atamanov et al. (2019) (section 4). The database can be downloaded in csv.

The data will be pulled from the WDI and combined with metadata from the Povcalnet

Scoring is as follows: Quality (1 points total): 1 Point. Comparable data lasting at least two years within past 5 years 0 Points. No comparable data within past 5 years

library(povcalnetR) 

#the code below is based on public released code by povcalnet team:
#https://github.com/worldbank/Global_Poverty_Blogs/blob/master/bg_povcalnet_comparability/R/comparability_breaks.R

# some contants
year_range <- 1990:2020
metadata_path <- "https://development-data-hub-s3-public.s3.amazonaws.com/ddhfiles/506801/povcalnet_comparability.csv"

# Load data ---------------------------------------------------------------

metadata <- read_csv(metadata_path)
cov_lkup <- c(3, 2, 1, 4)
names(cov_lkup) <- c("N", "U", "R", "A")

dat_lkup <- c(2,1)
names(dat_lkup) <- c("income","consumption")


pcn <- povcalnet()
pcn$coveragetype <- cov_lkup[pcn$coveragetype]
pcn$datatype <- dat_lkup[pcn$datatype]

df <- pcn %>%
  mutate(countrycode=as.character(countrycode)) %>%
  inner_join(metadata, by = c("countrycode", "year", "coveragetype", "datatype"))


#Now loop from 2016 and 2019, keeping just data inside last 5 years.
for (reference_year in 2004:2019) {
  
  temp<-df %>%
        filter(coveragetype %in% c(3,4)) %>% #keep just nationally representative samples
        mutate(frequency=((reference_year-as.numeric(year))<=5) & (reference_year>=as.numeric(year))) %>% 
        filter(frequency==TRUE) %>%
        group_by(countrycode, comparability) %>% #for each country and comparability type, get number of comparable estimates
        summarise(SPI.D1.5.POV=n())  %>%
        ungroup() %>%
        group_by(countrycode) %>% #now get a total by country with the max number of comparable estimates
        summarise(SPI.D1.5.POV=max(SPI.D1.5.POV, na.rm=T)) %>%
        mutate(SPI.D1.5.POV=if_else(SPI.D1.5.POV>=2,1,0)) %>% #only give point if there is at least two observations that are comparable
        mutate(date=reference_year,
                 iso3c=countrycode) %>%
        left_join(country_metadata) %>%
        select( country,iso3c, date, starts_with('SPI.D1.5.POV')) 



  assign(paste("D3.1.AKI",reference_year,sep="_"), temp)
}

#now append together and save
for (i in c(2004:2019)) {
  
  temp<-get(paste('D3.1.AKI_',i, sep=""))
  
  if (!exists('D3.1.AKI')) {
    D3.1.AKI<-temp
  } else {
    D3.1.AKI<-D3.1.AKI %>%
      bind_rows(temp) %>%
      arrange(-date, iso3c)
  }
}

Mortality rate, under-5 (per 1,000 live births)

UN IGME makes all available source data on child mortality rates available with metadata on quality.

https://childmortality.org/data/

Source data can bedivided into data included in the estimation model and data excluded from the estimation model (note: data may be excluded for any one of several reasons including data quality or by rule—for example, indirect estimates from summary birth histories are not included when direct estimates from the full birth history from the same survey or census are available).

Countries are assessed for whether they can produce indicators over a five year period that meet the thresholds set by UN IGME.

Quality (1 points total): 1 Point. At least three indicators that met UN IGME standards within past 5 years
0.67 Points. Two indicators that met UN IGME standards within past 5 years 0.33 Points. One indicators that met UN IGME standards within past 5 years 0 Points. None within past 5 years

Data was pulled on April 13, 2020.

#Read in data from UN Inter-agency Group for Child Mortality Estimation



D3.3.AKI.MORT <- read_csv(file=paste(raw_dir, '3.1_DPSS/D3.3_child_mort_RAW_v01.csv', sep="/")) %>%
  filter(INDICATOR=='Under-five mortality rate' & SEX=='Total') %>% #keep just observations for under 5 child mortality and for both sexes
  filter(OBS_STATUS=='Included in IGME') %>% # Also keep only surveys that met IGME criteria for inclusion as a nationally representative statistic
  mutate(date=as.numeric(str_extract(TIME_PERIOD, "^.{4}")),
         country=REF_AREA,
         D3.CHLD.MORT=OBS_VALUE)

#Now loop from 2016 and 2019, keeping just data inside last 5 years.
for (reference_year in 2004:2019) {
  temp <-D3.3.AKI.MORT %>%
          mutate(frequency=((reference_year-as.numeric(date))<=5) & (reference_year>=as.numeric(date))) %>%
          mutate(SPI.FREQ.D1.5.CHLD.MORT=if_else(frequency==TRUE,1,0)) %>% #create 0,1 variable for whether data point exists for country
          group_by(country) %>%
          summarise(SPI.FREQ.D1.5.CHLD.MORT=sum(SPI.FREQ.D1.5.CHLD.MORT, na.rm=T)) %>%
          mutate(SPI.FREQ.D1.5.CHLD.MORT=case_when(
            SPI.FREQ.D1.5.CHLD.MORT>=3 ~ 1,
            SPI.FREQ.D1.5.CHLD.MORT==2 ~ 0.67,
            SPI.FREQ.D1.5.CHLD.MORT==1 ~ 0.33,
            SPI.FREQ.D1.5.CHLD.MORT==0 ~ 0,
            TRUE ~ 0
          )) %>%
          mutate(SPI.D1.5.CHLD.MORT=SPI.FREQ.D1.5.CHLD.MORT) %>%
          mutate(date=reference_year) %>%
          select( country, date, starts_with('SPI.')) %>%
          select(-SPI.FREQ.D1.5.CHLD.MORT)


  assign(paste("D3.3.AKI",reference_year,sep="_"), temp)
}

#now append together and save
for (i in c(2004:2019)) {
  
  temp<-get(paste('D3.3.AKI_',i, sep=""))
  
  if (!exists('D3.3.AKI')) {
    D3.3.AKI<-temp
  } else {
    D3.3.AKI<-D3.3.AKI %>%
      bind_rows(temp) %>%
      arrange(-date, country)
  }
}

Debt service (PPG and IMF only, % of exports of goods, services and primary income)

For this indicator, Debt service (PPG and IMF only, % of exports of goods, services and primary income), we will pull data from the WDI but modify the scoring using the WDI metadata on whether the external debt data is actual, estimated, or preliminary. The status “as reported (actual)” indicates that the country was fully current in its reporting under the DRS and that World Bank staff are satisfied that the reported data give an adequate and fair representation of the country’s total public debt. “Preliminary” data are based on reported or collected information, but because of incompleteness or other reasons, an element of staff estimation is included. “Estimated” data indicate that countries are not current in their reporting and that a significant element of staff estimation has been necessary for producing the data tables.

Scoring is as follows:

Quality:

1 Points. Actual value 0.67 Points. Preliminary value 0.33 Points. Estimated value 0 Points. No value

# pull in some WDI metadata which will be used for constructing AKI indicators.
# WDI metadata was gathered using previous vintages of WDI from 2016-19
# Metadata was gathered and saved as csv files in the 011_data folder

for (i in 2016:2019) {
  temp <- read_csv(file = paste(raw_dir, "/metadata/WDI_metadata_",i,".csv", sep="" )) %>%
    as_tibble(.name_repair='universal') %>%
    mutate(National.accounts.reference.year=as.numeric(National.accounts.reference.year),
           date=i)
  
    assign(paste("WDI_metadata",i,sep="_"), temp)
}

WDI_metadata <- bind_rows(WDI_metadata_2016, WDI_metadata_2017, WDI_metadata_2018, WDI_metadata_2019)
#reshape metaadata file
D3.15.AKI <- WDI_metadata %>%
  transmute(iso3c=if_else(is.na(Country.Code), Code, Country.Code),
            date=date,
            External_debt_Reporting=External.debt.Reporting.status,
            Income.Group=Income.Group) %>%
  mutate(SPI.D1.5.DT.TDS.DPPF.XP.ZS= case_when(
            External_debt_Reporting=='Actual' ~ 1,
            External_debt_Reporting=='Preliminary' ~ 0.67,
            External_debt_Reporting=='Estimate' ~ 0.33,
            TRUE ~ 0
          )) %>% 
  mutate(SPI.D1.5.DT.TDS.DPPF.XP.ZS=if_else((Income.Group=="High income" & is.na(External_debt_Reporting)),1,SPI.D1.5.DT.TDS.DPPF.XP.ZS)) %>% #fix an issue where high income countries are not judged on their debt reporting
  ungroup() %>%
  select(iso3c, date,  contains('SPI.D1.5.DT.TDS.DPPF.XP.ZS')) 
#now combine AKI databases and write to csv
D3.AKI <- spi_df_empty %>%
  left_join(D3.1.AKI) %>%
  left_join(D3.3.AKI) %>%
  left_join(D3.15.AKI) %>%
  right_join(spi_df_empty) %>%
  mutate_at(vars(starts_with('SPI.D1.5.')), ~if_else(is.na(.),0,as.numeric(.))) 


spi_df <- spi_df %>%
  left_join(D3.AKI)
aki <- c(
             SPI.D1.5.POV='Poverty headcount ratio at $1.90 a day (2011 PPP) (% of population)',
             SPI.D1.5.CHLD.MORT='Mortality rate, under-5 (per 1,000 live births)', 
             SPI.D1.5.DT.TDS.DPPF.XP.ZS='Debt service (PPG and IMF only, % of exports of goods, services and primary income)'
)


for (ind in names(aki)) {
  ind <- ind
  names(aki)
  print(ind)
  temp_map <- D3.AKI %>%
    filter(.data[[ind]] >= 0)
  
  spi_mapper('temp_map', ind, aki[[ind]])
}
## [1] "SPI.D1.5.POV"

## [1] "SPI.D1.5.CHLD.MORT"

## [1] "SPI.D1.5.DT.TDS.DPPF.XP.ZS"

Data Services

Cleaning for Data Services Indicators. Data Services (4 Indicators):
- 2.1_DSDR - Indicator 2.1: Data releases
- 2.2_DSOA - Indicator 2.2: Online access
- 2.3_DSAS - Indicator 2.3: Advisory/ Analytical Services
- 2.4_DSDS - Indicator 2.4: Data services

Indicator 2.1: Data Releases

Data Dissemination Standard (SDDS) and electronic General Data Dissemination Standard (e-GDDS) were established by the International Monetary Fund (IMF) for member countries that have or that might seek access to international capital markets, to guide them in providing their economic and financial data to the public. Although subscription is voluntary, the subscribing member needs to be committed to observing the standard and provide information about its data and data dissemination practices (metadata). The metadata are posted on the IMF’s SDDS and e-GDDS websites.

1 Point. Subscribing to IMF SDDS+ or SDDS standards 0.5 Points. Subscribing to IMF e-GDDS standards 0 Points. Otherwise

Request_metadata <- GET(url = "http://api.worldbank.org/v2/country/all/indicator/5.21.01.01.sdds?format=json&date=2004:2015&per_page=5000")
Response_metadata <- content(Request_metadata, as = "text", encoding = "UTF-8")

# Parse the JSON content and convert it to a data frame.
D2.1_DSDR_sci <- jsonlite::fromJSON(Response_metadata, flatten = TRUE) %>%
  data.frame() %>%
  transmute(
    iso3c=countryiso3code,
    country=country.value,
    date=as.numeric(date),
    SDDS=value
  ) %>%
  left_join(spi_df_empty) %>% #add on country metadata
  filter(!is.na(income)) %>%
  select(iso3c, country, date, SDDS  ) 



#read in metadata file.

#pull data for several of the standards from WDI metadata

df <- WDI_metadata

# Manipulate and clean final data
df <- df %>%
  filter(!is.na(Income.Group))  #keep just countries (drop aggregations)


D2.1_DSDR <- df %>%
  mutate(iso3c=if_else(is.na(Country.Code), Code, Country.Code),
         country=Table.Name) %>%
  select(c('iso3c', 'country', 'date',  'IMF.data.dissemination.standard')  ) %>%
  mutate(IDDS=IMF.data.dissemination.standard) %>%
  mutate(SPI.D2.1.GDDS=case_when(
    IDDS=="Special Data Dissemination Standard Plus (SDDS+)" | IDDS=="Special Data Dissemination Standard (SDDS)"~ 1, 
    IDDS=="Enhanced General Data Dissemination System (e-GDDS)"~ 0.5,
    TRUE ~ 0 ),
    SDDS=case_when(
     IDDS=="Special Data Dissemination Standard (SDDS)"~ 1, 
    TRUE ~ 0 ))  %>%
  bind_rows(D2.1_DSDR_sci) %>%
  rename(RAW.D2.1.IDDS=IDDS) %>%
  select(iso3c, country, date, RAW.D2.1.IDDS, SPI.D2.1.GDDS  ) %>%
  arrange(date, country) 

D2.1_DSDR_map <- D2.1_DSDR %>%
  filter(RAW.D2.1.IDDS>0)

spi_mapper('D2.1_DSDR_map', 'SPI.D2.1.GDDS', 'SDDS Data Standards in Place' )

#add to spi databases
spi_df <- spi_df %>%
  left_join(D2.1_DSDR)

Indicator 2.2: Online access

This indicator measures the richness and openness of online access.

Source

Our source for this indicator is Open Data Watch. From Open Data watch:

The Open Data Inventory (ODIN) assesses the coverage and openness of official statistics to help identify gaps, promote open data policies, improve access, and encourage dialogue between national statistical offices (NSOs) and data users. ODIN 2018/19 includes 178 countries, including most all OECD countries. Two-year comparisons are for all countries with two years of data between 2015-2017. Scores can be compared across topics and countries.

We use the Openness score from ODIN for this measure. The score ranges from 0-100. It contains scores along five dimensions:
- Machine Readability
- Non-Proprietary format
- Download Options
- Metadata Available
- Terms of Use

A description for each of these five dimensions is below:

Machine Readability

Openness element 1 measures whether data are available in a machine readable format such as XLS, XLSX, CSV, and JSON. Machine-readable file formats allow users to easily process data using a computer. When data are made available in formats that are not machine readable, users cannot easily access and modify the data, which severely restricts the scope of the data’s use. In many cases PDF versions of datasets within reports can be useful to users, as the text in conjunction with the tables gives context and explanation to the figures which helps less technical users understand the data. Because of this, ODIN assessments do not penalize countries for making datasets available in PDF or other non-machine readable formats, unless these formats are the only option for exporting data. Scores are not penalized for having identical datasets in both machine readable and non-readable formats. Compression formats do not affect machine readability scores, only non-proprietary scores (see next page). Scores are given by data category, not indicator.

Non-Proprietary format

For the elements of data openness, scoring is calculated independent of the data coverage. If data files are compressed in RAR format (which is proprietary), data for that indicator should be considered proprietary even if the enclosing files are in a non-proprietary format. Files compressed in ZIP format are not affected.

Download Options

Openness element 3 measures whether data are available with three different download options: bulk download, API, and user-select options. A bulk download is defined at the indicator level as: The ability to download all data recorded in ODIN for a particular indicator (all years, disaggregations, and subnational data) in one file, or multiple files that can be downloaded simultaneously. Bulk downloads are a key component of the Open Definition, which requires data to be “provided as a whole . . . and downloadable via the internet.” User-selectable download options are defined as: Users must be able to select an indicator and at least one other dimension to create a download or table. These dimensions could include time periods, geographic disaggregations, or other recommended disaggregations. An option to choose the file export format is not enough. API stands for Application Programming Interface. Ideally, APIs should be clearly displayed on the website. ODIN assumes APIs are available for the NSOs entire data collection used in ODIN, unless clearly stated. ODIN assessors do not register for use or test API functionality. For more information on APIs, see this guide. Scores are given by data category, not indicator.

Metadata Available

Openness element 4 measures whether metadata are made available. Scores are given by data category, not indicator. Metadata are defined at the indicator level as information about how the data are defined/calculated and collected. ODIN classifies metadata into three categories: (1) Not Available, (2) Incomplete, and (3) Complete. The following must be available to classify metadata as complete: • Definition of the indicator, or definition of key terms used in the indicator description (as applicable), or how the indicator was calculated. • Publication (date of upload), compilation date (date on front of report is not sufficient), or date dataset was last updated. • Name of data source (what agency collected the data). If the metadata only have one or two of the above elements, they are scored as incomplete

Terms of Use

Openness element 5 measures whether data are available with an open terms of use. Generally, terms of use (TOU) will apply to an entire website or data portal (unless otherwise specified). In these cases, all data found on the same website and/or portal will receive the same score. If a portal is located on the same domain as the NSO website, the terms of use on the NSO site will apply. If the data are located on a portal or website on a different domain, another terms of use will need to be present. For a policy/ license to be accepted as a terms of use, it must clearly refer to the data found on the website. Terms of use that refer to nondata content (such as pictures, logos, etc.) of the website are not considered. A copyright symbol at the bottom of the page is not sufficient. A sentence indicating a recommended citation format is not sufficient. Terms of use are classified the following ways: (1) Not Available, (2) Restrictive, (3) Semi-Restrictive, and (4) Open. If the TOU contains one or more restrictive clauses, it receives 0 points and is classified as “restrictive.” Restrictive clauses include:

For more details, consult the ODIN technical documentation: https://docs.google.com/document/d/1ubPL1l_3im9bjlCVZ6W2ICAy6UAiXl1hGeA1aXImkxI/edit#

  #read in ODIN data
  for (i in 2015:2018) {
   temp <- read_csv(paste(raw_dir, '/2.2_DSOA/','ODIN_',i,'.csv', sep=""))  %>%
        as_tibble(.name_repair = 'universal') %>%
        mutate(date=i) %>%
        filter(Data.categories=='All Categories')

    assign(paste('openness_df',i,sep="_"), temp)
  }

#bind different years together
openness_df <- bind_rows(openness_df_2015, openness_df_2016, openness_df_2017, openness_df_2018)


openness_df <- openness_df %>%
    select(Country.Code, date, Machine.readable, Non.proprietary, Download.options, Metadata.available, Terms.of.use, Openness.subscore) %>%
    rename(iso3c=Country.Code) %>%
    group_by( iso3c) %>%
    right_join(country_metadata) %>%
    mutate(
      across(c('Machine.readable', 'Non.proprietary', 'Download.options', 'Metadata.available', 'Terms.of.use', 'Openness.subscore'),~if_else(is.na(.), 0, .)           )
      
           )  

#do some quick renaming and formatting
openness_df_temp1 <- openness_df %>% 
  rename_with(~paste('RAW.D2.2',., sep="."), .cols=c('Machine.readable', 'Non.proprietary', 'Download.options', 'Metadata.available', 'Terms.of.use', 'Openness.subscore') ) 


openness_df_temp2 <- openness_df %>% 
  mutate(across(c('Machine.readable', 'Non.proprietary', 'Download.options', 'Metadata.available', 'Terms.of.use', 'Openness.subscore'), ~./100)) %>%
  rename_with(~paste('SPI.D2.2',., sep="."), .cols=c('Machine.readable', 'Non.proprietary', 'Download.options', 'Metadata.available', 'Terms.of.use', 'Openness.subscore') ) 

openness_df <- openness_df_temp1 %>%
  left_join(openness_df_temp2)

#add to spi dataframe
spi_df <- spi_df %>%
  left_join(openness_df)

Indicator 2.3: Advisory/ Analytical Services

No established source exists for this indicator. This is experimental.

Indicator 2.4: Data services

NSO has a listing of surveys and microdata sets that can provide the necessary data and reference for follow-up. Upon well-defined request and procedure per the national law and practice, users and practitioners can obtain the data collected from the households and businesses when needed.

NADA is an open source microdata cataloging system, compliant with the Data Documentation Initiative (DDI) and Dublin Core’s RDF metadata standards. It serves as a portal for researchers to browse, search, compare, apply for access, and download relevant census or survey datasets, questionnaires, reports and other information.

1 Point. Yes 0 Points. No

#read in csv file.
D2.4_NADA <- read_csv(file = paste(raw_dir, '/2.4_DSDS/', "D2.4.NADA.csv", sep="/" )) %>%
  mutate(SPI.D2.4.NADA=case_when(
    NADA==1 ~ 1, 
    NADA==0 ~ 0, 
    TRUE ~ 0 
  ))  %>%
  rename(RAW.D2.4.NADA=NADA,
         RAW.D2.4.NADA_text=NADA_text) %>%
  select(iso3c, country, date, RAW.D2.4.NADA,RAW.D2.4.NADA_text, SPI.D2.4.NADA  ) %>%
  arrange(date, country)

D2.4_NADA_map <- D2.4_NADA %>%
  filter(SPI.D2.4.NADA>0)

spi_mapper('D2.4_NADA_map', 'RAW.D2.4.NADA', 'NADA in Place' )

#add to spi databases
spi_df <- spi_df %>%
  left_join(D2.4_NADA)

Data Products

Cleaning for Data Products Indicators. Data Products (16 Indicators):

Scoring Approach

  1. Download the latest SDG indicator data from UN Stats (https://unstats.un.org/sdgs/indicators/en/#) using their API

  2. Transform the data so that for each indicator we can create a score documenting whether a value exists for the country in a year, whether the value is based on country data, country data adjusted, estimated, or modelled data according the UN Stats metadata. This will only include tier 1 indicators.

  3. Combine the resulting data into a single set of indicators for use in the Statistical Performance Indicators dashboard and index by calculating the average across SDGs. This results in 17 total indicators. One for each SDG, which is the share of indicators with a value meeting quality criteria defined below.

Below is a paraphrased description from the UN stats webpage (https://unstats.un.org/sdgs/indicators/indicators-list/):

The global indicator framework for Sustainable Development Goals was developed by the Inter-Agency and Expert Group on SDG Indicators (IAEG-SDGs) and agreed upon at the 48th session of the United Nations Statistical Commission held in March 2017.

The global indicator framework includes 231 unique indicators. Please note that the total number of indicators listed in the global indicator framework of SDG indicators is 247. However, twelve indicators repeat under two or three different targets.

For each value of the indicator, the responsible international agency has been requested to indicate whether the national data were adjusted, estimated, modelled or are the result of global monitoring. The “nature” of the data in the SDG database is determined as follows:

  • Country data (C): Produced and disseminated by the country (including data adjusted by the country to meet international standards);

  • Country data adjusted (CA): Produced and provided by the country, but adjusted by the international agency for international comparability to comply with internationally agreed standards, definitions and classifications;

  • Estimated (E): Estimated based on national data, such as surveys or administrative records, or other sources but on the same variable being estimated, produced by the international agency when country data for some year(s) is not available, when multiple sources exist, or when there are data quality issues;

  • Modelled (M): Modelled by the agency on the basis of other covariates when there is a complete lack of data on the variable being estimated;

  • Global monitoring data (G): Produced on a regular basis by the designated agency for global monitoring, based on country data. There is no corresponding figure at the country level.

Scoring

For each indicator, we will produce a value for each country with the following coding scheme:

We give countries no credit for modeled data, because the country did not produce indicators in a form that was directly usable for reporting on an SDG indicator.

When we average over all indicators in a goal to get a score, we compute a 5 year moving average to avoid year to year variability in reporting for SDGs. The overall score for an SDG is then the 5 year average of the percentage of indicator values based on country, country data adjusted, or estimated or Global Monitoring data that were available for the SDG.

Because of the large data files and runtime of the program to calculate these indicators, the code to produce these indicators is in a separate file. https://github.com/stacybri/UN_Stats_SDG_Indicators_SPI/blob/master/02_programs/un_stats_cleaning.Rmd

un_sdg_df <- read_csv(paste(raw_dir,'/3_DP/SPI_D3_UNSD_data_',window,'yr.csv',sep="")) %>%
  rename(SPI.D3.1.POV   = SPI.D3.1,
         SPI.D3.2.HNGR  = SPI.D3.2,
         SPI.D3.3.HLTH  = SPI.D3.3,
         SPI.D3.4.EDUC  = SPI.D3.4,
         SPI.D3.5.GEND  = SPI.D3.5,
         SPI.D3.6.WTRS  = SPI.D3.6,
         SPI.D3.7.ENRG  = SPI.D3.7,
         SPI.D3.8.WORK  = SPI.D3.8,
         SPI.D3.9.INDY  = SPI.D3.9,
         SPI.D3.10.NEQL = SPI.D3.10,
         SPI.D3.11.CITY = SPI.D3.11,
         SPI.D3.12.CNSP = SPI.D3.12,
         SPI.D3.13.CLMT = SPI.D3.13,
         SPI.D3.14.LFWT = SPI.D3.14,
         SPI.D3.15.LAND = SPI.D3.15,
         SPI.D3.16.INST = SPI.D3.16,
         SPI.D3.17.PTNS = SPI.D3.17
) %>%
  select(country, date, starts_with("SPI")) %>%
  select(-SPI.D3.14.LFWT)

#add to spi databases
spi_df <- spi_df %>%
  left_join(un_sdg_df)

#map the values
un_sdg_map <- un_sdg_df %>%
  select(country, date, starts_with("SPI")) 

spi_mapper('un_sdg_map','SPI.D3.1.POV','Goal 1: No Poverty')

spi_mapper('un_sdg_map','SPI.D3.2.HNGR','Goal 2: No Hunger')

spi_mapper('un_sdg_map','SPI.D3.3.HLTH','Goal 3: Good Health and Well-being')

spi_mapper('un_sdg_map','SPI.D3.4.EDUC','Goal 4: Quality Education  ')

spi_mapper('un_sdg_map','SPI.D3.5.GEND','Goal 5: Gender Equality ')

spi_mapper('un_sdg_map','SPI.D3.6.WTRS','Goal 6: Clean Water and Sanitation ')

spi_mapper('un_sdg_map','SPI.D3.7.ENRG','Goal 7: Affordable and Clean Energy')

spi_mapper('un_sdg_map','SPI.D3.8.WORK','Goal 8: Decent Work and Economic Growth  ')

spi_mapper('un_sdg_map','SPI.D3.9.INDY','Goal 9: Industry, Innovation and Infrastructure ')

spi_mapper('un_sdg_map','SPI.D3.10.NEQL','Goal 10: Reduced Inequality   ')

spi_mapper('un_sdg_map','SPI.D3.11.CITY','Goal 11: Sustainable Cities and Communities')

spi_mapper('un_sdg_map','SPI.D3.12.CNSP','Goal 12: Responsible Consumption and Production   ')

spi_mapper('un_sdg_map','SPI.D3.13.CLMT','Goal 13: Climate Action')

#spi_mapper('un_sdg_map','SPI.D3.14.LFWT','Goal 14: Life Below Water')
spi_mapper('un_sdg_map','SPI.D3.15.LAND','Goal 15: Life on Land')

spi_mapper('un_sdg_map','SPI.D3.16.INST','Goal 16: Peace and Justice Strong Institutions')

spi_mapper('un_sdg_map','SPI.D3.17.PTNS','Goal 17: Partnerships to achieve the Goal  ')

Data Sources

Cleaning for the Data Sources Indicators. Data Sources (4 Indicators):
- 4.1_SOCS - Indicator 4.1: censuses and surveys
- 4.2_SOAD - Indicator 4.2: administrative data
- 4.3_SOGS - Indicator 4.3: geospatial data
- 4.4_SOPC - Indicator 4.4: private/citizen generated data

Indicator 4.1: censuses and surveys

This indicator draws from data collected by the Statistical Performance Indicators team. The following censuses and surveys are considered:

  • Population & Housing census
  • Agriculture census
  • Business/establishment census
  • Household Survey on income/ consumption/ expenditure/ budget/ Integrated Survey
  • Agriculture survey
  • Labor Force Survey
  • Health/Demographic survey
  • Business/establishment survey

Scoring details

Population & Housing census

Population censuses collect data on the size, distribution and composition of population and information on a broad range of social and economic characteristics of the population. It also provides sampling frames for household and other surveys. Housing censuses provide information on the supply of housing units, the structural characteristics and facilities, and health and the development of normal family living conditions. Data obtained as part of the population census, including data on homeless persons, are often used in the presentation and analysis of the results of the housing census. It is recommended that population and housing censuses be conducted at least every 10 years.

1 Point. Population census done within last 10 years
0.5 Points. Population census done within last 20 years 0 Points. Otherwise

Agriculture census

Agriculture censuses collect information on agricultural activities, such as size of holding, land tenure, land use, employment and production, and provide basic structural data and sampling frames for agricultural surveys. Censuses of agriculture normally involves collecting key structural data by complete enumeration of all agricultural holdings, in combination with more detailed structural data using sampling methods. It is recommended that agricultural censuses be conducted at least every 10 years.

1 Point. census done within last 10 years
0.5 Points. census done within last 20 years
0 Points. Otherwise

Business/establishment census

Business/establishment censuses provide valuable information on all economic activities, number of employed and size of establishments in the economy. Business Register information is establishment-based and includes business location, organization type (e.g. subsidiary or parent), industry classification, and operating data (e.g., receipts and employment).

1 Point. census done within last 10 years
0.5 Points. census done within last 20 years
0 Points. Otherwise

Household Survey on income/consumption/expenditure/budget/Integrated Survey

These surveys collect data on household income (including income in kind), consumption and expenditure. They typically include income, expenditure, and consumption surveys, household budget surveys, integrated surveys. It is recommended that surveys on income and expenditure be conducted at least every 3 to 5 years.

1 Point. 3 or more surveys done within past 10 years
0.6 Points. 2 surveys done within past 10 years;
0.3 Points. 1 survey done within past 10 years;
0 Points. None within past 10 years

Agriculture survey

Agricultural surveys refer to surveys of agricultural holdings based on the sampling frames established by the agricultural census. These are surveys on agricultural land, production, crops and livestock, aquaculture, labor and cost, and time use. Some issues, such as gender and food security, are of interest to most agriculture surveys.

1 Point. 3 or more surveys done within past 10 years
0.6 Points. 2 surveys done within past 10 years;
0.3 Points. 1 survey done within past 10 years;
0 Points. None within past 10 years

Labor Force Survey

Labor force survey is a standard household-based survey of work-related statistics at the national and sub-national employment or unemployment levels, rates or trends. The surveys also provide the characteristics of the employed or unemployed, including labor force status by age or gender, breakdowns between employees and the self-employed, public versus private sector employment, multiple job-holding, hiring, job creation, and duration of unemployment.

1 Point. 3 or more surveys done within past 10 years
0.6 Points. 2 surveys done within past 10 years;
0.3 Points. 1 survey done within past 10 years;
0 Points. None within past 10 years

Health/Demographic survey

Health surveys collect information on various aspects of health of populations, such as health expenditure, access, utilization, and outcomes. They typically include Demographic and Health Surveys. It is recommended that health surveys be conducted at least every 3 to 5 years.

1 Point. 3 or more surveys done within past 10 years
0.6 Points. 2 surveys done within past 10 years;
0.3 Points. 1 survey done within past 10 years;
0 Points. None within past 10 years

Business/establishment survey

The business/establishment survey provides information on employment, hours, and earnings of employees from a sample of business establishments including private and public, entities that are classified based on an establishment’s principal activity from the business or establishment census. Establishment surveys include surveys of businesses, farms, and institutions. They may ask for information about the establishment itself and/or employee characteristics and demographics.

1 Point. 3 or more surveys done within past 10 years
0.6 Points. 2 surveys done within past 10 years;
0.3 Points. 1 survey done within past 10 years;
0 Points. None within past 10 years

#pull data for population and agriculture census from WDI metadata

df <- WDI_metadata

# Manipulate and clean final data
df <- df %>%
  filter(!is.na(Income.Group))  #keep just countries (drop aggregations)
  

pop_census_df <- df %>%
  mutate(iso3c=if_else(is.na(Country.Code), Code, Country.Code),
         country=Table.Name) %>%
  select(c('iso3c', 'country', 'date',  'Latest.population.census')  ) %>%
  mutate(last_val=str_extract(Latest.population.census, "\\d{4}") )%>%
    mutate(last_val=as.numeric(last_val)) %>%
    mutate(indicator=case_when(
      (date-last_val<=10) & (date-last_val>0) ~ 1,
      (date-last_val<=20) & (date-last_val>0) ~ 0.5,
      TRUE ~ 0 )
    )  %>%
    ungroup() %>%
    select(c('iso3c', 'country', 'date', 'Latest.population.census', 'indicator')  ) %>%
    arrange(date, country)
  
ag_census_df <- df %>%
  mutate(iso3c=if_else(is.na(Country.Code), Code, Country.Code),
         country=Table.Name) %>%
  select(c('iso3c', 'country', 'date',  'Latest.agricultural.census')  ) %>%
  mutate(last_val=str_extract(Latest.agricultural.census, "\\d{4}") )%>%
    mutate(last_val=as.numeric(last_val)) %>%
    mutate(indicator=case_when(
      (date-last_val<=10) & (date-last_val>0) ~ 1,
      (date-last_val<=20) & (date-last_val>0) ~ 0.5,
      TRUE ~ 0 )
    )  %>%
    ungroup() %>%
    select(c('iso3c', 'country', 'date', 'Latest.agricultural.census', 'indicator')  ) %>%
    arrange(date, country)
census_fun  <- function(data, input_var) {
  
  data <- data
  input_var <- input_var

  #read in csv file.
  cs_df <- read_csv(file = paste(raw_dir, '/4.1_SOCS/', data, "_manual.csv", sep="" )) %>%
    group_by(iso3c, country) %>% 
    rename(input_var = !! input_var) %>%
    nest() %>% # The next chunk of code will split our string with the years of the census (i.e. "2000, 2010") in to separate rows.  We will then aggregate up.
    mutate(
      temp_col = map(
        data, 
        ~ str_extract_all(.x$input_var, "\\d{4}") %>% 
          flatten() %>% 
          map_chr(~return(.x)) %>% 
          as_tibble()
      )
    ) %>% 
    unnest(keep_empty = TRUE) %>% # Now we have a database with the observations equal to Country*Census observations.  From here we can calculate latest census, etc.
    mutate(indicator_date=as.numeric(value)) %>%
    select('country','indicator_date','input_var')
  
    #append IHSN data on surveys
  cs_df <- cs_df %>%
    bind_rows(read_csv(file = paste(raw_dir, '/4.1_SOCS/', data, "_IHSN.csv", sep="" ))) %>%
    group_by(country, indicator_date) %>%
    summarise(input_var=first(na.omit(input_var)  ),
            ihsn_dates=first(na.omit(ihsn_dates)  ) 
             )
    
  
  #Now calculate our SPI score for this indicator
  for (i in 2004:2019) {
   temp <- cs_df %>%
    mutate(date=i) %>%
    mutate(recency_indicator=((date>indicator_date)) ) %>% #restrict to censuses that do not occur after reference date
    mutate(indicator_date=if_else(recency_indicator==TRUE, indicator_date, as.numeric(NA))) %>%
    group_by(country, date) %>%
    summarise(last_val=max(indicator_date, na.rm=T),
      input_var=first(input_var),
      ihsn_dates=first(ihsn_dates)) %>%
    mutate(indicator=case_when(
      (date-last_val<=10) & (date-last_val>0) ~ 1,
      (date-last_val<=20) & (date-last_val>0) ~ 0.5,
      TRUE ~ 0 )
    )  %>%
     ungroup() %>%
    select(c( 'country', 'date', 'input_var','ihsn_dates', 'indicator')  ) %>%
    arrange(date, country)

    assign(paste('temp',i,sep="_"), temp)
  }

  temp <- temp_2019
  
  for (i in 2004:2018) {
    temp <- bind_rows(temp, get(paste('temp',i,sep="_")))
  }
  temp
}



survey_fun  <- function(data, input_var) {
  
  data <- data
  input_var <- input_var

  #read in csv file that was manually collected.
  cs_df <- read_csv(file = paste(raw_dir, '/4.1_SOCS/', data, "_manual.csv", sep="" )) %>%
    group_by(iso3c, country) %>% 
    rename(input_var = !! input_var) %>%
    nest() %>% # The next chunk of code will split our string with the years of the census (i.e. "2000, 2010") in to separate rows.  We will then aggregate up.
    mutate(
      temp_col = map(
        data, 
        ~ str_extract_all(.x$input_var, "\\d{4}") %>% 
          flatten() %>% 
          map_chr(~return(.x)) %>% 
          as_tibble()
      )
    ) %>% 
    unnest(keep_empty = TRUE) %>% # Now we have a database with the observations equal to Country*Census observations.  From here we can calculate latest census, etc.
    mutate(indicator_date=as.numeric(value)) %>%
    select('country','indicator_date','input_var')
  
  #append IHSN data on surveys
  cs_df <- cs_df %>%
    bind_rows(read_csv(file = paste(raw_dir, '/4.1_SOCS/', data, "_IHSN.csv", sep="" ),
                       col_types = list(col_character(),col_double(), col_character()))) %>%
    group_by(country, indicator_date) %>%
    summarise(input_var=first(na.omit(input_var)  ),
            ihsn_dates=first(na.omit(ihsn_dates)  ) 
             )
    
  
  #Now calculate our SPI score for this indicator
  for (i in 2004:2019) {
   temp <- cs_df %>%
    mutate(date=i) %>%
    mutate(recency_indicator=((date-indicator_date<=10) & (date-indicator_date>0)) ) %>% #restrict to surveys inside 10 year period
    group_by( country, date) %>% #group by country and create indicator for how many surveys over 10 year period
    summarise(indicator=case_when(
      sum(recency_indicator)>=3 ~ 1, 
      sum(recency_indicator)==2 ~ 0.6, 
      sum(recency_indicator)==1 ~ 0.3, 
      TRUE ~ 0 ),
      input_var=first(input_var),
      ihsn_dates=first(ihsn_dates)) %>%
  ungroup() %>%
  select(c( 'country', 'date', 'input_var','ihsn_dates', 'indicator')  ) %>%
  arrange(date, country)

    assign(paste('temp',i,sep="_"), temp)
  }

  temp <- temp_2019
  
  for (i in 2004:2018) {
    temp <- bind_rows(temp, get(paste('temp',i,sep="_")))
  }
  temp
}


#Population Censuses
cs1_df <-pop_census_df %>%
  rename(RAW.D4.1.1.POPU.CENSUS=Latest.population.census,
         SPI.D4.1.1.POPU=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))

#Agriculture census  
cs2_df <-ag_census_df %>%
  rename(RAW.D4.1.2.AGRI.CENSUS=Latest.agricultural.census,
         SPI.D4.1.2.AGRI=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))

#Business/establishment census 
cs3_df <-census_fun('D4.1.3.CEN.BIZZ', 'BIZZ.CENSUS') %>%
  rename(RAW.D4.1.3.BIZZ.CENSUS=input_var,
         RAW.D4.1.3.BIZZ.CENSUS_IHSN=ihsn_dates,
         SPI.D4.1.3.BIZZ=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))

#Household Survey on income/ consumption/ expenditure/ budget/ Integrated Survey
cs4_df <-survey_fun('D4.1.4.SVY.HOUS', 'HOUS.SURVEYS') %>%
  rename(RAW.D4.1.4.HOUS.SURVEYS=input_var,
         RAW.D4.1.4.HOUS.SURVEYS_IHSN=ihsn_dates,
         SPI.D4.1.4.HOUS=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))

#Agriculture survey 
cs5_df <-survey_fun('D4.1.5.SVY.AGRI', 'AGRI.SURVEYS') %>%
  rename(RAW.D4.1.5.AGRI.SURVEYS=input_var,
         RAW.D4.1.5.AGRI.SURVEYS_IHSN=ihsn_dates,
         SPI.D4.1.5.AGSVY=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))

#Labor Force Survey 
cs6_df <-survey_fun('D4.1.6.SVY.LABR', 'LABR.SURVEYS') %>%
  rename(RAW.D4.1.6.LABR.SURVEYS=input_var,
         RAW.D4.1.6.LABR.SURVEYS_IHSN=ihsn_dates,
         SPI.D4.1.6.LABR=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))

#Health/Demographic survey
cs7_df <-survey_fun('D4.1.7.SVY.HLTH', 'HLTH.SURVEYS') %>%
  rename(RAW.D4.1.7.HLTH.SURVEYS=input_var,
         RAW.D4.1.7.HLTH.SURVEYS_IHSN=ihsn_dates,
         SPI.D4.1.7.HLTH=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))

#Business/establishment survey  
cs8_df <-survey_fun('D4.1.8.SVY.BIZZ', 'BIZZ.SURVEYS') %>%
  rename(RAW.D4.1.8.BIZZ.SURVEYS=input_var,
         RAW.D4.1.8.BIZZ.SURVEYS_IHSN=ihsn_dates,
         SPI.D4.1.8.BZSVY=indicator) %>%
  select(country, date, starts_with("SPI"), starts_with("RAW"))


#brind all censuses and surveys together
cs_df <- spi_df_empty %>%
  left_join(cs1_df) %>%
  left_join(cs2_df) %>%
  left_join(cs3_df) %>%
  left_join(cs4_df) %>%
  left_join(cs5_df) %>%
  left_join(cs6_df) %>%
  left_join(cs7_df) %>%
  left_join(cs8_df) 

#add to spi databases
spi_df <- spi_df %>%
  left_join(cs_df)

#now do the figures 
cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.1.POPU))
spi_mapper('cs_df_map', 'SPI.D4.1.1.POPU', 'Population Census Available in Past 20 Years in 2019' )

cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.2.AGRI))
spi_mapper('cs_df_map', 'SPI.D4.1.2.AGRI', 'Agriculture Census Available in Past 20 Years in 2019' )

cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.3.BIZZ))
spi_mapper('cs_df_map', 'SPI.D4.1.3.BIZZ', 'Business/Establishment Census Available in Past 20 Years in 2019' )

cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.4.HOUS))
spi_mapper('cs_df_map', 'SPI.D4.1.4.HOUS', 'Household Survey Availablility in Past 10 Years in 2019' )

cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.5.AGSVY))
spi_mapper('cs_df_map', 'SPI.D4.1.5.AGSVY', 'Agriculture Survey Availablility in Past 10 Years in 2019' )

cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.6.LABR))
spi_mapper('cs_df_map', 'SPI.D4.1.6.LABR', 'Labor Force Survey Availablility in Past 10 Years in 2019' )

cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.7.HLTH))
spi_mapper('cs_df_map', 'SPI.D4.1.7.HLTH', 'Health Survey Availablility in Past 10 Years in 2019' )

cs_df_map <- cs_df %>%  filter(!is.na(SPI.D4.1.8.BZSVY))
spi_mapper('cs_df_map', 'SPI.D4.1.8.BZSVY', 'Business Survey Availablility in Past 10 Years in 2019' )

Indicator 4.2: administrative data

The following indicator checks whether administrative data is available for the following topic areas: Social Protection, Education, Population & Health, and Labor

Social Protection Admin Data

  • Atlas of Social Protection Indicators of Resilience and Equity (ASPIRE) is compilation of Social Protection and Labor (SPL) indicators to analyze scope and performance of SPL programs.
  • ASPIRE has indicators for 136 countries on:
    • Social assistance
    • Social insurance
    • Labor market programs
  • Based on both program-level administrative data and national household survey data
  • Data extends from 2001 to 2018

Scoring is 1 if administrative data is available to produce beneficiary counts or expenditures for any social protection and labor program, 0 otherwise. In order to smooth out gaps in reporting, we take a moving 5 year average of the score.

#read data
aspire_df_raw <- read_csv(paste(raw_dir, '4.2_SOAD','ASPIRE_sources.csv', sep="/"))

#cleaning of aspire data
aspire_df <- aspire_df_raw %>%
    mutate(date=as.numeric(year)) %>%
    filter(!is.na(date)) %>%
    group_by( ccode, date) %>%
    summarise(ben_count_avail=(!is.na(mean(ben, na.rm=T))),
              ben_exp_avail=(!is.na(mean(exp_b, na.rm=T)))) %>%
    rename(iso3c=ccode) %>%
    left_join(country_metadata) %>%
    mutate(ben_info_avail=(ben_count_avail==TRUE | ben_exp_avail==TRUE)
           )

write_excel_csv(aspire_df, paste(output_dir, 'SPL_admin_data_availability.csv', sep="/"))

#create 5 year moving average
aspire_fun <- function(date_start, date_end) {
  temp <- aspire_df %>%
      filter(between(date,date_start,date_end) ) %>%  
      group_by(iso3c, country) %>%
      mutate(ben_info_avail=if_else(ben_info_avail==TRUE,as.numeric(ben_info_avail), 0)) %>%
      summarise(ben_info_avail=round(mean(ben_info_avail),1) #get an average of this across countries
              ) %>%
      mutate(SPI.D4.2.1.SPL=if_else(is.na(ben_info_avail),0, ben_info_avail),
            RAW.D4.2.1.SPL=ben_info_avail) %>%
      mutate(date=date_end) %>%
      select(c('iso3c', 'country', 'date', 'RAW.D4.2.1.SPL', 'SPI.D4.2.1.SPL')  )
      
  

}



####
# X Year moving average
####
#create this database for each year from 2004 to 2019 using a X year average
for (i in c(2004:2019)) {
  
  start=i-(window-1)
  end=i
  
  temp_df <- aspire_fun(start,end)
  assign(paste('aspire_',end, sep=""), temp_df)
}

if (exists('aspire_df')) {
  rm('aspire_df')
}
#now append together and save
for (i in c(2004:2019)) {
  
  temp<-get(paste('aspire_',i, sep=""))
  
  if (!exists('aspire_df')) {
    aspire_df<-temp
  } else {
    aspire_df<-aspire_df %>%
      bind_rows(temp) %>%
      arrange(-date, iso3c)
  }
}


#add to spi databases
spi_df <- spi_df %>%
  left_join(aspire_df)

aspire_map <- aspire_df

spi_mapper('aspire_map', 'SPI.D4.2.1.SPL', 'Administrative Data Available on Beneficiary Counts or Expenditures using ASPIRE' )

Education Admin Data

  • UNESCO UIS has shared a database containing data we can use on administrative data systems

  • We score countries based on whether there is:

    • Data tracking SDG 4.1.2 Administration of a nationally-representative learning assessment (a) in Grade 2 or 3; (b) at the end of primary education; and (c) at the end of lower secondary education

    • Data tracking whether countries produce the following from administrative data sources:

      • Out-of-school rate by school age and sex
      • 4.2.2 Participation rate in organized learning (one year before the official primary entry age), by sex

In order to score this indicator, we calculate the fraction of the three types of indicators that were produced in a country in a year. In order to smooth out variation from year to year in reporting or conducting national assessments, we take a moving 5 year average.

#read data from UNESCO API
#get list of indicators to download
indicators <- 'ADMI_GRADE2OR3PRIM_READ+ADMI_ENDOFPRIM_READ+ADMI_ENDOFLOWERSEC_READ+ADMI_GRADE2OR3PRIM_MAT+ADMI_ENDOFPRIM_MAT+ADMI_ENDOFLOWERSEC_MAT+ROFST_1_CP+ROFST_1_F_CP+ROFST_1_M_CP+ROFST_2_CP+ROFST_2_F_CP+ROFST_2_M_CP+ROFST_3_CP+ROFST_3_F_CP+ROFST_3_M_CP+ROFST_1T2_CP+ROFST_1T2_F_CP+ROFST_1T2_M_CP+ROFST_2T3_CP+ROFST_2T3_F_CP+ROFST_2T3_M_CP+ROFST_1T3_CP+ROFST_1T3_F_CP+ROFST_1T3_M_CP+NERA_AGM1_CP+NERA_AGM1_F_CP+NERA_AGM1_M_CP.'

#get list of countries
countries <- 'AFG+ALB+DZA+ASM+AND+AGO+AIA+ATG+ARG+ARM+ABW+AUS+AUT+AZE+BHS+BHR+BGD+BRB+BLR+BEL+BLZ+BEN+BMU+BTN+BOL+BIH+BWA+BRA+VGB+BRN+BGR+BFA+BDI+KHM+CMR+CAN+CPV+CYM+CAF+TCD+CHL+CHN+HKG+MAC+COL+COM+COG+COK+CRI+CIV+HRV+CUB+CUW+CYP+CZE+PRK+COD+DNK+DJI+DMA+DOM+ECU+EGY+SLV+GNQ+ERI+EST+SWZ+ETH+FJI+FIN+FRA+GUF+PYF+GAB+GMB+GEO+DEU+GHA+GIB+GRC+GRL+GRD+GLP+GUM+GTM+GIN+GNB+GUY+HTI+VAT+HND+HUN+ISL+IND+IDN+IRN+IRQ+IRL+ISR+ITA+JAM+JPN+JOR+KAZ+KEN+KIR+KWT+KGZ+LAO+LVA+LBN+LSO+LBR+LBY+LIE+LTU+LUX+MDG+MWI+MYS+MDV+MLI+MLT+MHL+MTQ+MRT+MUS+MEX+FSM+MCO+MNG+MNE+MSR+MAR+MOZ+MMR+NAM+NRU+NPL+NLD+ANT+NCL+NZL+NIC+NER+NGA+NIU+MKD+NOR+OMN+PAK+PLW+PSE+PAN+PNG+PRY+PER+PHL+POL+PRT+PRI+QAT+KOR+MDA+REU+ROU+RUS+RWA+SHN+KNA+LCA+SPM+VCT+WSM+SMR+STP+SAU+SEN+SRB+SYC+SLE+SGP+SXM+SVK+SVN+SLB+SOM+ZAF+SSD+ESP+LKA+SDN+XDN+SUR+SWE+CHE+SYR+TJK+THA+TLS+TGO+TKL+TON+TTO+TUN+TUR+TKM+TCA+TUV+UGA+UKR+ARE+GBR+TZA+USA+URY+UZB+VUT+VEN+VNM+WLF+YEM+ZMB+ZWE+SDG+40675+40330+40334+40344+40606+40617+40603+40614+40618+40612+40616+40619+40611+40613+40630+40650+40651+40656+40642+40620+40640+UIS+40510+40525+40530+40505+40515+40520+40500+40535+40540+40550+WB+40044+40042+40030+40043+40041/all'

start <- '2000'
end <- '2019'

#build the API query
url <- paste('http://data.uis.unesco.org/RestSDMX/sdmx.ashx/GetData/SDG4_DS/',indicators, countries,'?startTime=',start,'&endTime=',end,sep="")

#read the data
unesco_df_raw <- readsdmx::read_sdmx(url)

#cleaning of unesco data
unesco_df <- unesco_df_raw %>%
    mutate(date=as.numeric(Time)) %>%
    mutate(type = case_when( #categorize based on whether they are assessment, out of school, or participation data
      grepl('ADMI', SDG_IND) ~ "NAS", #Administration of a nationally-representative learning assessment (a) in Grade 2 or 3; (b) at the end of primary education; and (c) at the end of lower secondary education 
      grepl('ROFST', SDG_IND) ~ "OOS", # Out-of-school rate by school age and sex
      grepl('NERA', SDG_IND) ~ "ORGL" # Participation rate in organized learning (one year before the official primary entry age), by sex
    )) %>%
    mutate(edu_admin_available=(ObsValue!=NaN & !is.na(ObsValue))) %>% #get a variable for wehther admin based value exists for indicator
    group_by( LOCATION2017,type, date) %>%
    summarise(edu_admin_available=mean(as.numeric(edu_admin_available))) %>% 
    ungroup() %>%
    pivot_wider(
      names_from='type',
      names_glue="RAW.D4.2.2.EDU.{type}",
      values_from='edu_admin_available',
      values_fill=0
    ) %>%
    rename(iso3c=LOCATION2017) %>%
    right_join(spi_df_empty) %>%
    mutate(across(starts_with('RAW.D4.2.2.EDU'),~if_else(is.na(.),0,.))) %>%
    group_by(iso3c) %>%
    arrange(-date, iso3c) %>%
    mutate(across(starts_with('RAW.D4.2.2.EDU'),~zoo::rollmean(.,k=window,fill=NA,align='left'),.names="{col}.MA5")) %>% #X year rolling average
    ungroup() %>%
    mutate(SPI.D4.2.2.EDU=(RAW.D4.2.2.EDU.NAS.MA5+RAW.D4.2.2.EDU.OOS.MA5+RAW.D4.2.2.EDU.ORGL.MA5)/3) %>%
  select(c('iso3c', 'country', 'date', 'RAW.D4.2.2.EDU.NAS','RAW.D4.2.2.EDU.OOS','RAW.D4.2.2.EDU.ORGL', 'SPI.D4.2.2.EDU')  )

#add to spi databases
spi_df <- spi_df %>%
  left_join(unesco_df)

unesco_map <- unesco_df 

spi_mapper('unesco_map', 'SPI.D4.2.2.EDU', 'Education Administrative Data Available According to UIS' )

Population & Health Admin Data

  • This indicator is formed using World Bank metadata on whether the Civil Registration and Vital Statistics (CRVS) system is complete in the country.

Civil registration is the act of recording and documenting of vital events in a person’s life (including birth, marriage, divorce, adoption, and death and cause of death) and is a fundamental function of national governments. Birth registration establishes an individual’s legal identity at birth. A legal identity, name, nationality, and proof of age, are important human rights. They enable individuals to be included in various government, social and private services, and include the right to vote, etc. Vital statistics are compiled using civil registration information on these vital events. The availability of reliable and up-to-date vital statistics depends on the level of development of civil registration programs. An effective civil registration and vital statistics (CRVS) system is critical for planning and monitoring programs across several sectors.

By complete, that is representing 90 per cent or more of the events occurring in the specified year.

Source: World Bank WDI Metadata.

#get data directly from WDI metadata.  Vintages are stored in metadata folder
# Request_metadata <- GET(url = "https://api.worldbank.org/v2/sources/2/country/all/metadata?per_page=30000&format=json")
# Response_metadata <- content(Request_metadata, as = "text", encoding = "UTF-8")
# 
# # Parse the JSON content and convert it to a data frame.
# JSON_metadata <- jsonlite::fromJSON(Response_metadata, flatten = TRUE) %>%
#   data.frame()
# 
# #do some conversion to produce a dataframe
# df <- JSON_metadata$source.concept %>%
#   data.frame() 
# 
# #do some more cleaning and conversion
# df <- df$variable %>%
#   data.frame()   %>%
#   rename(iso3c=id) %>%
#   unnest(metatype) %>%
#   pivot_wider(
#     id_cols=iso3c,
#     names_from=id,
#     values_from=value
#   ) 

df <- WDI_metadata

# Manipulate and clean final data
df <- df %>%
  filter(!is.na(Income.Group))  #keep just countries (drop aggregations)
  
df$SPI.D4.2.3.CRVS<-as.numeric(grepl("Yes", df$Vital.registration.complete)) #create 0,1 variable for vital registration

crvs_df <- df %>%
  mutate(iso3c=if_else(is.na(Country.Code), Code, Country.Code),
         country=Table.Name,
         RAW.D4.2.3.CRVS=Vital.registration.complete) %>%
  select(c('iso3c', 'country', 'date', 'RAW.D4.2.3.CRVS', 'SPI.D4.2.3.CRVS')  )


#pull old data from SCI
Request_metadata <- GET(url = "http://api.worldbank.org/v2/country/all/indicator/3.11.01.03.popreg?format=json&date=2004:2015&per_page=5000")
Response_metadata <- content(Request_metadata, as = "text", encoding = "UTF-8")

# Parse the JSON content and convert it to a data frame.
crvs_df2 <- jsonlite::fromJSON(Response_metadata, flatten = TRUE) %>%
  data.frame() %>%
  transmute(
    iso3c=countryiso3code,
    country=country.value,
    date=as.numeric(date),
    crvs=value
  ) %>%
  mutate(SPI.D4.2.3.CRVS=as.numeric(crvs),
         RAW.D4.2.3.CRVS=as.character(crvs)) %>%
  left_join(spi_df_empty) #add on country metadata


# Manipulate and clean final data
crvs_df2 <- crvs_df2 %>%
  filter(!is.na(income)) %>% #keep just countries (drop aggregations)
  select(c('iso3c', 'country', 'date', 'RAW.D4.2.3.CRVS', 'SPI.D4.2.3.CRVS')  )

#join updated data with SCI data
crvs_df <- crvs_df %>%
  bind_rows(crvs_df2)

#add to spi databases
spi_df <- spi_df %>%
  left_join(crvs_df)


crvs_map <- crvs_df 

spi_mapper('crvs_map', 'SPI.D4.2.3.CRVS', 'Complete Civil Registration & Vital Statistics Data Available According to WDI' )

Labor Admin Data

  • ILO shared database containing all administrative data sources used to produce ILO statistics (ILOSTAT)

    • May not be comprehensive of all administrative datasets available in a country
    • But gives some indication of whether labor statistics produced using Admin data
  • Database contains the following admin sources:

    • Insurance records
    • Labour inspectorate records
    • Records of employers’ organizations
    • Employment office records
    • Records of workers’ organizations
    • Other administrative records and related sources
  • Database extends from 2010 to 2019 and covers 177 countries.

To produce a score, we calculate the percentage of these six admin sources above that are available for a country in a given year. In order to smooth out gaps in reporting, we take a moving 5 year average of the score.

#read data
ilo_df_raw <- read_csv(paste(raw_dir, '4.2_SOAD','ILOSTAT_sources.csv', sep="/"))

#cleaning of aspire data
ilo_df <- ilo_df_raw %>%
  filter(!grepl('legislation',Source)) %>% # filter out labor legislation, which is included but not reflective of needs.
  mutate(type = case_when( #categorize based on whether they are assessment, out of school, or participation data
      (Source.type=="Insurance records" ) ~ "INSUR", #Insurance records 
      (Source.type=="Labour inspectorate records" ) ~ "INSP", # Labour inspectorate records  
      (Source.type=="Records of employers' organizations" ) ~ "EMPORG", # Records of employers' organizations
      (Source.type=="Employment office records" ) ~ "EMPOFF", # Employment office records
      (Source.type=="Records of workers' organizations"  ) ~ "WRKORG", # Records of workers' organizations
      (Source.type=="Other administrative records and related sources" ) ~ "OTHER" # Other administrative records and related sources
                        ),
      admin_available=1) %>%
  select(iso3c, date, type,Source ) %>%
      pivot_wider(
      names_from='type',
      names_glue="RAW.D4.2.4.LBR.{type}",
      values_from='Source',
      values_fill=NULL
    ) 


#apply carryforward to fill in missing values
ilo_df <- ilo_df %>%
  right_join(spi_df_empty) %>%
  arrange(iso3c, date) %>%
  group_by(iso3c) %>%
  mutate(across(starts_with('RAW.D4.2.4.LBR'),
                ~if_else(.!='NULL',1, 0),
                .names="{col}_available")) %>%
  mutate(ILO.Source.type.filled=(RAW.D4.2.4.LBR.OTHER_available +
                                RAW.D4.2.4.LBR.INSUR_available +
                                RAW.D4.2.4.LBR.EMPOFF_available+
                                RAW.D4.2.4.LBR.WRKORG_available+
                                RAW.D4.2.4.LBR.INSP_available  +
                                RAW.D4.2.4.LBR.EMPORG_available)/6) %>%
  group_by(iso3c) %>%
  arrange(-date, iso3c) %>%
  mutate(across(starts_with('ILO.Source.type.filled'),~zoo::rollmean(.,k=window,fill=NA,align='left'),.names="{col}.MA5")) %>% #X year rolling average
  ungroup() %>%
  mutate(SPI.D4.2.4.LBR=if_else(is.na(ILO.Source.type.filled.MA5),0, ILO.Source.type.filled.MA5)) %>%
  select(c('iso3c', 'country', 'date', 'SPI.D4.2.4.LBR'), starts_with('RAW.D4.2.4.LBR')  ) %>%
  select(-ends_with('available'))

#add to spi databases
spi_df <- spi_df %>%
  left_join(ilo_df)  


ilo_map <- ilo_df 

spi_mapper('ilo_map', 'SPI.D4.2.4.LBR', 'Labor Administrative Data Available According to ILO' )

Indicator 4.3: geospatial data

New indicator based on references to geospatial data in metadata relating to content on NSO website

Source

Our source for this indicator is Open Data Watch. From Open Data watch:

The Open Data Inventory (ODIN) assesses the coverage and openness of official statistics to help identify gaps, promote open data policies, improve access, and encourage dialogue between national statistical offices (NSOs) and data users. ODIN 2018/19 includes 178 countries, including most all OECD countries. Two-year comparisons are for all countries with two years of data between 2015-2017. Scores can be compared across topics and countries.

We use their indicator on whether indicators are available at the first or second administrative level. To identify the first administrative levels, ODIN largely draws on the ISO 3166-2 standard. In many countries, first administrative levels refer to governorates, regions, or province. No official list exists for the second administrative level classifications. If geographical disaggregation exists that does not qualify as first administrative level, assume that the data are disaggregated to the second administrative level as long as the classification appears to be a further divisions of the first administrative level.

Scoring for the ODIN indicators for geospatial information is below:

  • 1 point if all published data in a data category are available at first/second administrative level.
  • 0.5 points if some published data in a data category are available at first/second administrative level.
  • 0 points if no data are available at this level

There are 21 data categories.

Social Statistics
1. Population and Vital Statistics
2. Education Facilities
3. Education Outcomes
4. Health Facilities
5. Health Outcomes
6. Reproductive Health
7. Gender Statistics
8. Crime and Justice Statistics
9. Poverty Statistics

Economic Statistics
10. National Accounts
11. Labor Statistics
12. Price Indexes
13. Government Finance
14. Money and Banking
15. International Trade
16. Balance of Payments

Environmental Statistics
17. Land Use
18. Resource Use
19. Energy Use
20. Pollution
21. Built Environment

For the first administrative unit: Money & Banking, International Trade, and Balance of Payments are not scored for this element. For various indicators, lenient interpretations are used for first administrative divisions.

For the second administrative unit: Money & Banking, International Trade, Balance of Payments, National Accounts, Government Finance ,Pollution, Energy Use, Price Indexes, and Resource Use are not scored for this element. For various indicators within categories, second administrative level data is not required as well.

In the scores we present below, we show a score between 0 and 1 with a maximum score of 1, which would mean the country has geo data in full for 100% of elements. A score of 0 indicates no data at all for any elements.

More details on the geographic disaggregation considerations can be found in their technical manual:

https://docs.google.com/document/d/1ubPL1l_3im9bjlCVZ6W2ICAy6UAiXl1hGeA1aXImkxI/edit

  #read in ODIN data
  for (i in 2015:2018) {
   temp <- read_csv(paste(raw_dir, '/2.2_DSOA/','ODIN_',i,'.csv', sep=""))  %>%
        as_tibble(.name_repair = 'universal') %>%
        mutate(date=i) %>%
        filter(Data.categories=='All Categories')

    assign(paste('geo_df',i,sep="_"), temp)
  }

#bind different years together
geo_df <- bind_rows(geo_df_2015, geo_df_2016, geo_df_2017, geo_df_2018)


#create geo scores
geo_df <- geo_df %>%
    select(Country.Code, date, First.administrative.level, Second.administrative.level) %>%
    rename(iso3c=Country.Code) %>%
    group_by( iso3c) %>%
    right_join(country_metadata) %>%
    mutate(D4.3.GEO.first.admin.level=if_else(is.na(First.administrative.level), 0, First.administrative.level),
           D4.3.GEO.second.admin.level=if_else(is.na(Second.administrative.level), 0, Second.administrative.level))    
  

#do some quick renaming and formatting
geo_df_temp1 <- geo_df %>% 
  rename_with(~paste('RAW',., sep="."), .cols=c('D4.3.GEO.first.admin.level', 'D4.3.GEO.second.admin.level') ) 


geo_df_temp2 <- geo_df %>% 
  mutate(across(c('D4.3.GEO.first.admin.level', 'D4.3.GEO.second.admin.level'), ~./100)) %>%
  rename_with(~paste('SPI',., sep="."), .cols=c('D4.3.GEO.first.admin.level', 'D4.3.GEO.second.admin.level') ) 

geo_df <- geo_df_temp1 %>%
  left_join(geo_df_temp2)

#add to spi df
spi_df <- spi_df %>%
  left_join(geo_df)

Indicator 4.4: private/citizen generated data

New indicator based on references to private/citizen generated data in metadata relating to content on NSO website.

Covid Mobility Data Availability

We have seen an increased use of private/citizen generated data during the COVID-19 pandemic. One way in which it has been used is for tracking mobility of citizens to understand the social distancing measures citizens are taking. As a measure of private/citizen generated data we make use of Apple and Google Mobility tracking data made publicly available during the pandemic.

Source:

Google LLC “Google COVID-19 Community Mobility Reports”. https://www.google.com/covid19/mobility/ Accessed: 2020-07-23.

Apple “Mobility Trends Reports”. https://www.apple.com/covid19/mobility/ Accessed: 2020-07-23.

Data Infrastructure

Data Infrastructure (5 Indicators):
- 5.1_DILG - Indicator 5.1: legislation and governance
- 5.2_DISM - Indicator 5.2: standards
- 5.3_DISK - Indicator 5.3: skills
- 5.4_DIPN - Indicator 5.4: partnerships
- 5.5_DIFI - Indicator 5.5: finance

Indicator 5.1: legislation and governance

The legislation and governance indicator will be drawn from SDG indicator 17.18.2 (national statistical legislation compliance with UN Fundamental Principles of Official Statistics), existence of National Statistical Council, national statistical strategy generation, national statistical plan. Also include some other legislative aspects that foster good use of statistics eg freedom of information, privacy/transparency, good governance (eg free and fair elections).

This indicator measures whether the national statistical legislation complies with United Nations Fundamental Principles of Statistics (SDG 17.18.2)

Scores is 1 if the country has a national statistical legislation compliant with United Nations Fundamental Principles of Statistics. Scores of 0 or scores with missing values are treated the same (both given a score of zero).

The source is Paris 21 and UNSD. Data accessed using UNSD SDG API on 2020-09-18

D5.1_DILG <- un_pull('SG_STT_FPOS', '2004', '2019') %>%
  select(iso3c, date,value) %>%
  right_join(spi_df_empty) %>%
  mutate(RAW.D5.1.DILG=if_else((is.na(value) | value=="NaN"),as.numeric(NA), as.numeric(value)),
         SPI.D5.1.DILG=if_else((is.na(value) | value=="NaN"),0, as.numeric(value))) %>%
  select(-value)
# 
# #read in csv file.
# D5.1_DILG2 <- read_csv(file = paste(raw_dir, "5.1_DILG","5.1_DILG.csv", sep="/" )) %>%
#   as_tibble(.name_repair = 'universal') %>%
#   transmute(
#     country=Country,
#     date=Year,
#     SPI.5.1.DILG=Data.Value
#   ) %>%
#     mutate(country=case_when(
#     country=="Bahamas" ~ "Bahamas, The",                  
#     country=="Bolivia (Plurinational State of)"   ~  "Bolivia"   ,                  
#     country=="Côte d'Ivoire"  ~  "Cote d'Ivoire"                ,
#     country=="Democratic Republic of the Congo"  ~ "Congo, Dem. Rep."  ,           
#     country=="Congo"  ~ "Congo, Rep."        ,           
#     country=="Curacao"  ~  "Curacao"       ,                
#     country=="Czechia"   ~  "Czech Republic"     ,        
#     country=="Egypt"  ~ "Egypt, Arab Rep."        ,      
#     country=="Micronesia (Federated States of)"  ~ "Micronesia, Fed. Sts."  ,       
#     country=="United Kingdom"   ~  "United Kingdom"    ,         
#     country=="Gambia"    ~  "Gambia, The"     ,           
#     country=="Iran (Islamic Republic of)"  ~ "Iran, Islamic Rep." ,           
#     country=="Kyrgyzstan"   ~  "Kyrgyz Republic"   ,          
#     country=="Republic of Korea"   ~ "Korea, Rep."   ,               
#     country=="Lao People's Democratic Republic"    ~  "Lao PDR" ,                    
#     country=="Saint Kitts and Nevis   "   ~ "St. Kitts and Nevis",
#     country=="Saint Lucia"   ~ "St. Lucia",
#     country=="Republic of Moldova"   ~  "Moldova"   ,                  
#     country=="Democratic People's Republic of Korea"  ~  "Korea, Dem. People’s Rep." ,  
#     country=="Slovakia"   ~  "Slovak Republic"             ,
#     country=="United Republic of Tanzania"   ~  "Tanzania" ,                    
#     country=="United States of America"  ~ "United States"  ,                
#     country=="Saint Vincent and the Grenadines" ~ "St. Vincent and the Grenadines" ,
#     country=="Venezuela (Bolivarian Republic of)"  ~  "Venezuela, RB"   ,              
#     country=="British Virgin Islands"  ~  "British Virgin Islands" ,       
#     country=="Viet Nam"  ~ "Vietnam"        ,              
#     country=="Yemen"  ~ "Yemen, Rep.",
#     country=="United Kingdom of Great Britain and Northern Ireland" ~ "United Kingdom",
#     TRUE ~ country
#   )) %>%
#   mutate(RAW.5.1.DILG=if_else(SPI.5.1.DILG=='no data',as.character(NA), SPI.5.1.DILG),
#          SPI.5.1.DILG=if_else(SPI.5.1.DILG=='no data',as.numeric(NA), as.numeric(SPI.5.1.DILG))) %>%
#   right_join(spi_df_empty)

#add to spi databases
spi_df <- spi_df %>%
  left_join(D5.1_DILG)


D5.1_DILG_map <- D5.1_DILG %>%
  filter(!is.na(SPI.D5.1.DILG))

spi_mapper('D5.1_DILG_map', 'SPI.D5.1.DILG', 'National statistical legislation complies with United Nations Fundamental Principles of Statistics. Source: Paris21')

## Indicator 5.2: standards

#pull data for several of the standards from WDI metadata

df <- WDI_metadata

# Manipulate and clean final data
df <- df %>%
  filter(!is.na(Income.Group))  #keep just countries (drop aggregations)

5.2.1 System of National Accounts in use

The national accounts data are compiled using the concepts, definitions, framework, and methodology of the System of National Account 2008 (SNA2008) or European System of National and Regional Accounts (ESA 2010). The manual has evolved to meet the changing economic structure, to follow systematic accounting and ensure international compatibility.

Scoring: 1 point for using SNA2008 or ESA 2010, 0.5 points for using SNA 1993 or ESA 1995, 0 points otherwise

#read in metadata file.
D5.2.1.SNAU <- df %>%
  mutate(iso3c=if_else(is.na(Country.Code), Code, Country.Code),
         country=Table.Name) %>%
  select(c('iso3c', 'country', 'date',  'System.of.National.Accounts')  ) %>%
  mutate(SNAU=System.of.National.Accounts) %>%
  mutate(SNAU=str_extract(SNAU, "\\d{4}") ) %>%
  mutate(SPI.D5.2.1.SNAU=case_when(
    SNAU=="2008" ~ 1, 
    SNAU=="1993" ~ 0.5,
    TRUE ~ 0 
  ),
      RAW.D5.2.1.SNAU=System.of.National.Accounts) %>%
  arrange(date, country) %>%
  select(iso3c, country, date,RAW.D5.2.1.SNAU, SPI.D5.2.1.SNAU  ) 

5.2.2 National Accounts base year

National accounts base year is the year used as the base period for constant price calculations in the country’s national accounts. It is recommended that the base year of constant price estimates be changed periodically to reflect changes in economic structure and relative prices.

1 point for chained price, 0.5 for reference period within past 10 years, 0 points otherwise.

D5.2.2.NABY <- df %>%
  mutate(iso3c=if_else(is.na(Country.Code), Code, Country.Code),
         country=Table.Name) %>%
  select(c('iso3c', 'country', 'date',  'National.accounts.base.year')  ) %>%
  mutate(NABY=National.accounts.base.year) %>%
  mutate(NABY_dates=gsub("\\d{2}/","",NABY) ) %>%
  mutate(NABY_dates=str_extract(NABY_dates, "\\d{4}") ) %>%
  mutate(NABY_dates=if_else(NABY=="20015/2016","2016",NABY_dates)) %>% #fix an issue in WDI metadata
  mutate(SPI.D5.2.2.NABY=case_when(
    NABY=="Original chained constant price data are rescaled." ~ 1, 
    (date-as.numeric(NABY_dates))<=10 ~ 0.5, #within 10 years of reference period
    TRUE ~ 0 
  ),
  RAW.D5.2.2.NABY=NABY)  %>%
  select(iso3c, country, date, RAW.D5.2.2.NABY, SPI.D5.2.2.NABY  ) %>%
  arrange(date, country)

5.2.3 Classification of national industry

The industrial production data are compiled using the International Standard Industrial Classification of All Economic Activities (ISIC) Rev.4 and Statistical Classification of Economic Activities in the European Community (NACE) Rev.2. ISIC Rev.4 is a standard classification of economic activities arranged so that entities can be classified per the activity they carry out using criteria such as input, output and use of the products produced, more emphasis has been given to the character of the production process in defining and delineating ISIC classes for international comparability. The manual and classification have changed to cover the complete scope of industrial production, employment, and GDP and other statistical areas.

1 Point. Latest version is adopted (ISIC Rev 4, NACE Rev 2 or a compatible classification)

0.5 Points. Previous version is used (ISIC Rev 3, NACE Rev 1 or a compatible classification)

0 Points. Otherwise

#read in csv file.
D5.2.3.CNIN <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.3.CNIN.csv", sep="/" )) %>%
  mutate(SPI.D5.2.3.CNIN=case_when(
    str_to_lower(CNIN)=="nace rev2" | str_to_lower(CNIN)=="rev4" ~ 1, 
    str_to_lower(CNIN)=="nace rev1" | str_to_lower(CNIN)=="rev3" ~ 0.5, 
    TRUE ~ 0 
  ),
  RAW.D5.2.3.CNIN=CNIN)  %>%
  select(iso3c, country, date, RAW.D5.2.3.CNIN, SPI.D5.2.3.CNIN  ) %>%
  arrange(date, country)

5.2.4 CPI base year

Consumer Price Index serves as indicators of inflation and reflects changes in the cost of acquiring a fixed basket of goods and services by the average consumer.
Weights are usually derived from consumer expenditure surveys and the CPI base year refers to the year the weights were derived. It is recommended that the base year be changed periodically to reflect changes in expenditure structure.

1 Point. Annual chain linking. 0.5 Points. Base year in last 10 years. 0 points. Otherwise

#read in csv file.
D5.2.4.CPIBY <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.4.CPIBY.csv", sep="/" )) %>%
  mutate(SPI.D5.2.4.CPIBY=case_when(
    CPIBY=="annual chained" ~ 1, 
    (date-as.numeric(CPIBY))<=10 ~ 0.5, #within 10 years of reference period
    TRUE ~ 0 
  ),
  RAW.D5.2.4.CPIBY=CPIBY)  %>%
  select(iso3c, country, date, RAW.D5.2.4.CPIBY, SPI.D5.2.4.CPIBY  ) %>%
  arrange(date, country)

5.2.5 Classification of household consumption

Classification of Individual Consumption According to Purpose (COICOP) is used in household budget surveys, consumer price indices and international comparisons of gross domestic product (GDP) and its component expenditures.
Although COICOP is not strictly linked to any particular model of consumer behavior, the classification is designed to broadly reflect differences in income elasticities. It is an integral part of the SNA1993 and more detailed subdivision of the classes provide comparability between countries and between statistics in these different areas.

1 Point. Follow Classification of Individual Consumption by Purpose (COICOP) 0 Points. Otherwise

#read in csv file.
D5.2.5.HOUS <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.5.HOUS.csv", sep="/" )) %>%
  mutate(SPI.D5.2.5.HOUS=case_when(
    HOUS=="COICOP" ~ 1, 
    TRUE ~ 0 
  ),
  RAW.D5.2.5.HOUS=HOUS)  %>%
  select(iso3c, country, date, RAW.D5.2.5.HOUS, SPI.D5.2.5.HOUS  ) %>%
  arrange(date, country)

5.2.6 Classification of status of employment

Classification of status of employment refers to employment data that are compiled using the current international standard International Classification of Status in Employment (ISCE-93). It classifies jobs with respect to the type of explicit or implicit contract of employment between the job holder and the economic unit in which he or she is employed. Therefore, it aims to provide the basis for production of internationally comparable statistics on the employment relationship, including the distinction between salaried employment and self-employment.

1 Point. Follow International Labour Organization, International Classification of Status in Employment (ICSE-93) or 2012 North American Industry Classification System (NAICS). 0 Points Otherwise.

#read in csv file.
D5.2.6.EMPL <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.6.EMPL.csv", sep="/" )) %>%
  mutate(SPI.D5.2.6.EMPL=case_when(
    EMPL=="ICSE-93" | EMPL=="NAICS" ~ 1, 
    TRUE ~ 0 
  ),
  RAW.D5.2.6.EMPL=EMPL)  %>%
  select(iso3c, country, date, RAW.D5.2.6.EMPL, SPI.D5.2.6.EMPL  ) %>%
  arrange(date, country)

5.2.7 Central government accounting status

Government finance accounting status refers to the accounting basis for reporting central government financial data. For many countries’ government finance data, have been consolidated into one set of accounts capturing all the central government’s fiscal activities and following noncash recording basis.
Budgetary central government accounts do not necessarily include all central government units, the picture they provide of central government activities is usually incomplete.

1 Point. Consolidated central government accounting follows noncash recording basis
0.5 Points. Consolidated central government accounting follows cash recording basis
0 Points. Otherwise

#read in csv file.
D5.2.7.CGOV <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.7.CGOV.csv", sep="/" )) %>%
  mutate(SPI.D5.2.7.CGOV=case_when(
    CGOV=="AC" ~ 1, 
    CGOV=="CA" ~ 0.5,
    TRUE ~ 0 
  ),
  RAW.D5.2.7.CGOV=CGOV)  %>%
  select(iso3c, country, date, RAW.D5.2.7.CGOV, SPI.D5.2.7.CGOV  ) %>%
  arrange(date, country)

5.2.8 Compilation of government finance statistics

(GFSM) in use for compiling the data. It provides guidelines on the institutional structure of governments and the presentation of fiscal data in a format similar to business accounting with a balance sheet and income statement plus guidelines on the treatment of exchange rate and other valuation adjustments. The latest manual GFSM2014 is harmonized with the SNA2008.

1 Point. Follow the latest Government Finance Statistical Manual (2014)/ ESA2010
0.5 Points. Previous version is used (GFSM 2001)
0 Points. Otherwise

#read in csv file.
D5.2.8.FINA <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.8.FINA.csv", sep="/" )) %>%
  mutate(SPI.D5.2.8.FINA=case_when(
    FINA=="2014" | FINA=="ESA 2010"~ 1, 
    FINA=="2001" ~ 0.5,
    TRUE ~ 0 
  ),
  RAW.D5.2.8.FINA=FINA)  %>%
  select(iso3c, country, date, RAW.D5.2.8.FINA, SPI.D5.2.8.FINA  ) %>%
  arrange(date, country)

5.2.9 Compilation of monetary and financial statistics

Compilation of monetary and financial statistics refers to the Monetary and Financial Statistics Manual (MFSM) in use. It covers concepts, definitions, classifications of financial instruments and sectors, and accounting rules, and provides a comprehensive analytic framework for monetary and financial planning and policy determination. The Monetary and Finance Statistics: Compilation Guide (2008) provides detailed guidelines for the compilation of monetary and financial statistics in addition to MFSM.

1 Point. Follow the latest Monetary and Finance Statistics Manual (2000) or Monetary and Finance Statistics: Compilation Guide (2008/2016) 0 Points. Otherwise

#read in csv file.
D5.2.9.MONY <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.9.MONY.csv", sep="/" )) %>%
  mutate(SPI.D5.2.9.MONY=case_when(
    MONY=="MFSM 2000" | MONY=="MFSMCG 2016"~ 1, 
    TRUE ~ 0 
  ),
  RAW.D5.2.9.MONY=MONY)  %>%
  select(iso3c, country, date, RAW.D5.2.9.MONY, SPI.D5.2.9.MONY  ) %>%
  arrange(date, country)

5.2.10 Business process

The Generic Statistical Business Process Model (GSBPM) aims to describe statistics production in a general and process-oriented way. It is used both within and between statistical offices as a common basis for work with statistics production in different ways, such as quality, efficiency, standardization, and process-orientation. It is used for all types of surveys, and “business” is not related to “business statistics” but refers to the statistical office, simply expressed.

1 Point. GSBPM is in use 0 Points. Otherwise

#read in csv file.
D5.2.10.GSBP <- read_csv(file = paste(raw_dir, "5.2_DISM","D5.2.10.GSBP.csv", sep="/" )) %>%
  mutate(SPI.D5.2.10.GSBP=case_when(
    str_to_lower(GSBP)=="yes" ~ 1, 
    TRUE ~ 0 
  ),
  RAW.D5.2.10.GSBP=GSBP)  %>%
  select(iso3c, country, date, RAW.D5.2.10.GSBP, SPI.D5.2.10.GSBP  ) %>%
  arrange(date, country)

Create Overall Indicator

# join datasets together based on country and date
D5.2.MSC <- spi_df_empty %>%
  left_join(D5.2.1.SNAU) %>%
  left_join(D5.2.2.NABY) %>%
  left_join(D5.2.3.CNIN) %>%
  left_join(D5.2.4.CPIBY) %>%
  left_join(D5.2.5.HOUS) %>%
  left_join(D5.2.6.EMPL) %>%
  left_join(D5.2.7.CGOV) %>%
  left_join(D5.2.8.FINA) %>%
  left_join(D5.2.9.MONY) %>%
  left_join(D5.2.10.GSBP) %>%
  select(iso3c, country, date, everything()) %>%
  arrange(date, iso3c) 


#add to spi databases
spi_df <- spi_df %>%
  left_join(D5.2.MSC)

#now do the figures 
msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.1.SNAU))
spi_mapper('msc_df_map', 'SPI.D5.2.1.SNAU', 'System of National Accounts in use in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.2.NABY))
spi_mapper('msc_df_map', 'SPI.D5.2.2.NABY', 'National Accounts base year in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.3.CNIN))
spi_mapper('msc_df_map', 'SPI.D5.2.3.CNIN', 'Classification of national industry in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.4.CPIBY))
spi_mapper('msc_df_map', 'SPI.D5.2.4.CPIBY', 'CPI base year in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.5.HOUS))
spi_mapper('msc_df_map', 'SPI.D5.2.5.HOUS', 'Classification of household consumption in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.6.EMPL))
spi_mapper('msc_df_map', 'SPI.D5.2.6.EMPL', 'Classification of status of employment in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.7.CGOV))
spi_mapper('msc_df_map', 'SPI.D5.2.7.CGOV', 'Central government accounting status in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.8.FINA))
spi_mapper('msc_df_map', 'SPI.D5.2.8.FINA', 'Compilation of government finance statistics in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.9.MONY))
spi_mapper('msc_df_map', 'SPI.D5.2.9.MONY', 'Compilation of monetary and financial statistics in 2019' )

msc_df_map <- D5.2.MSC %>%  filter(!is.na(SPI.D5.2.10.GSBP))
spi_mapper('msc_df_map', 'SPI.D5.2.10.GSBP', 'Business process in 2019' )

Indicator 5.3: skills

This indicator assesses the systematic use of statistical knowledge with statistical terms and indicators in national policy documents. It is a composite indicator consisting of 4 sub-indices that aim to reflect the relevance of statistical evidence. It comprises four main dimensions: i) Basic consideration; ii) Diagnosis and quantification; iii) Statistical Analysis; iv) Disaggregation.

Score ranges from 0 to 100. The score is the weighted sum of each of the four components’ scores, whose relative weight is reported in brackets: i) Basic Consideration (25%); ii) Diagnosis and quantification (24%); iii) Statistical Analysis (22%); iv) Disaggregation (29%).

The source is Paris 21. Data accessed on August 6, 2020 from https://statisticalcapacitymonitor.org/indicator/127

#read in csv file.
D5.3_DISK <- read_csv(file = paste(raw_dir, "5.3_DISK","5.3_DISK.csv", sep="/" )) %>%
  as_tibble(.name_repair = 'universal') %>%
  transmute(
    country=Country,
    date=Year,
    SPI.D5.3.DISK=Data.Value
  ) %>%
    mutate(country=case_when(
    country=="Bahamas" ~ "Bahamas, The",                  
    country=="Bolivia (Plurinational State of)"   ~  "Bolivia"   ,                  
    country=="Côte d'Ivoire"  ~  "Cote d'Ivoire"                ,
    country=="Democratic Republic of the Congo"  ~ "Congo, Dem. Rep."  ,           
    country=="Congo"  ~ "Congo, Rep."        ,           
    country=="Curacao"  ~  "Curacao"       ,                
    country=="Czechia"   ~  "Czech Republic"     ,        
    country=="Egypt"  ~ "Egypt, Arab Rep."        ,      
    country=="Micronesia (Federated States of)"  ~ "Micronesia, Fed. Sts."  ,       
    country=="United Kingdom"   ~  "United Kingdom"    ,         
    country=="Gambia"    ~  "Gambia, The"     ,           
    country=="Iran (Islamic Republic of)"  ~ "Iran, Islamic Rep." ,           
    country=="Kyrgyzstan"   ~  "Kyrgyz Republic"   ,          
    country=="Republic of Korea"   ~ "Korea, Rep."   ,               
    country=="Lao People's Democratic Republic"    ~  "Lao PDR" ,                    
    country=="Saint Kitts and Nevis "   ~ "St. Kitts and Nevis",
    country=="Saint Lucia"   ~ "St. Lucia",
    country=="Republic of Moldova"   ~  "Moldova"   ,                  
    country=="Democratic People's Republic of Korea"  ~  "Korea, Dem. People’s Rep." ,  
    country=="Slovakia"   ~  "Slovak Republic"             ,
    country=="United Republic of Tanzania"   ~  "Tanzania" ,                    
    country=="United States of America"  ~ "United States"  ,                
    country=="Saint Vincent and the Grenadines" ~ "St. Vincent and the Grenadines" ,
    country=="Venezuela (Bolivarian Republic of)"  ~  "Venezuela, RB"   ,              
    country=="British Virgin Islands"  ~  "British Virgin Islands" ,       
    country=="Viet Nam"  ~ "Vietnam"        ,              
    country=="Yemen"  ~ "Yemen, Rep.",
    country=="United Kingdom of Great Britain and Northern Ireland" ~ "United Kingdom",
    TRUE ~ country
  )) %>%
  mutate(RAW.D5.3.DISK=if_else(SPI.D5.3.DISK=='no data',as.character(NA), SPI.D5.3.DISK),
         SPI.D5.3.DISK=if_else(SPI.D5.3.DISK=='no data',as.numeric(NA), as.numeric(SPI.D5.3.DISK))/100) %>%
  right_join(spi_df_empty)

#add to spi databases
spi_df <- spi_df %>%
  left_join(D5.3_DISK)


D5.3_DISK_map <- D5.3_DISK %>%
  filter(!is.na(SPI.D5.3.DISK))

spi_mapper('D5.3_DISK_map', 'SPI.D5.3.DISK', 'Systematic use of statistical knowledge with statistical terms and indicators in national policy documents. Source: Paris21')

Indicator 5.4: partnerships

No data is available for this indicator at this point.

Indicator 5.5: finance

Indicator based on SDG indicators (SDG 17.18.3 (national statistical plan that is fully funded and under implementation). This indicator measures whether the national statistical plan under implementation is fully funded. It relates to SDG 17.18.3 and is based on the annual Status Report on National Strategies for the Development of Statistics (NSDS).

Scores is 1 if the country has a national statistical plan that is fully funded and under implementation. Scores of 0 or scores with missing values are treated the same (both given a score of zero).

The source is Paris 21 and UNSD. Data accessed using UNSD SDG API on 2020-09-18

Source of this data is UNSD and Paris21.

#pull from unsd api
D5.5_DIFI <- un_pull('SG_STT_NSDSFND', '2004', '2019') %>%
  select(iso3c, date,value) %>%
  right_join(spi_df_empty) %>%
  mutate(RAW.D5.5.DIFI=if_else((is.na(value) | value=="NaN"),as.numeric(NA), as.numeric(value)),
         SPI.D5.5.DIFI=if_else((is.na(value) | value=="NaN"),0, as.numeric(value))) %>%
  select(-value)

# #read in csv file.
# D5.5_DIFI <- read_csv(file = paste(raw_dir, "5.5_DIFI","D5.5_DIFI.csv", sep="/" )) %>%
#   as_tibble(.name_repair = 'universal') %>%
#   transmute(
#     country=Country,
#     date=Year,
#     SPI.5.5.DIFI=Data.Value
#   ) %>%
#     mutate(country=case_when(
#     country=="Bahamas" ~ "Bahamas, The",                  
#     country=="Bolivia (Plurinational State of)"   ~  "Bolivia"   ,                  
#     country=="Côte d'Ivoire"  ~  "Cote d'Ivoire"                ,
#     country=="Democratic Republic of the Congo"  ~ "Congo, Dem. Rep."  ,           
#     country=="Congo"  ~ "Congo, Rep."        ,           
#     country=="Curacao"  ~  "Curacao"       ,                
#     country=="Czechia"   ~  "Czech Republic"     ,        
#     country=="Egypt"  ~ "Egypt, Arab Rep."        ,      
#     country=="Micronesia (Federated States of)"  ~ "Micronesia, Fed. Sts."  ,       
#     country=="United Kingdom"   ~  "United Kingdom"    ,         
#     country=="Gambia"    ~  "Gambia, The"     ,           
#     country=="Iran (Islamic Republic of)"  ~ "Iran, Islamic Rep." ,           
#     country=="Kyrgyzstan"   ~  "Kyrgyz Republic"   ,          
#     country=="Republic of Korea"   ~ "Korea, Rep."   ,               
#     country=="Lao People's Democratic Republic"    ~  "Lao PDR" ,                    
#     country=="Saint Kitts and Nevis   "   ~ "St. Kitts and Nevis",
#     country=="Saint Lucia"   ~ "St. Lucia",
#     country=="Republic of Moldova"   ~  "Moldova"   ,                  
#     country=="Democratic People's Republic of Korea"  ~  "Korea, Dem. People’s Rep." ,  
#     country=="Slovakia"   ~  "Slovak Republic"             ,
#     country=="United Republic of Tanzania"   ~  "Tanzania" ,                    
#     country=="United States of America"  ~ "United States"  ,                
#     country=="Saint Vincent and the Grenadines" ~ "St. Vincent and the Grenadines" ,
#     country=="Venezuela (Bolivarian Republic of)"  ~  "Venezuela, RB"   ,              
#     country=="British Virgin Islands"  ~  "British Virgin Islands" ,       
#     country=="Viet Nam"  ~ "Vietnam"        ,              
#     country=="Yemen"  ~ "Yemen, Rep.",
#     country=="United Kingdom of Great Britain and Northern Ireland" ~ "United Kingdom",
#     TRUE ~ country
#   )) %>%
#   mutate(RAW.5.5.DIFI=if_else(SPI.5.5.DIFI=='no data',as.character(NA), SPI.5.5.DIFI),
#          SPI.5.5.DIFI=if_else(SPI.5.5.DIFI=='no data',as.numeric(NA), as.numeric(SPI.5.5.DIFI))) %>%
#   right_join(spi_df_empty)

#add to spi databases
spi_df <- spi_df %>%
  left_join(D5.5_DIFI)





D5.5_DIFI_map <- D5.5_DIFI %>%
  filter(!is.na(SPI.D5.5.DIFI))

spi_mapper('D5.5_DIFI_map', 'SPI.D5.5.DIFI', 'Statistical plan fully funded. Source: Paris21')

Final Dataset

Below we will append the data together and save the final files to gether.

#add in population
pop_df <- wbstats::wb(country="all",
             indicator='SP.POP.TOTL',
             startdate=2004,
             enddate=2019) %>%
  mutate(date=as.numeric(date)) %>%
  mutate(population=value) %>%
  select(country, date, population)

# create final dataset
spi_df_final <- spi_df %>%
  select(country, iso3c, date, starts_with("SPI"), starts_with("RAW")) %>%
  right_join(spi_df_empty) %>%
  left_join(pop_df) %>%
  arrange(-date,country)


####
#lining up data to 2019 and filling in some values for OECD countries.  
####
#get a list of oecd countries
oecd_country_query <-  GET(url = "https://api.worldbank.org/v2/country?region=OED&format=json") %>%
  content( as = "text", encoding = "UTF-8") %>%
  jsonlite::fromJSON( flatten = TRUE) 

#do some conversion to produce a dataframe
oecd_country_df <- oecd_country_query[[2]] %>%
  as_tibble() 
  
country_mod_list <- oecd_country_df$name  #fill in the missing values for OECDs with 1s because by participating in OECD these countries have this
country_mod_list <- c(country_mod_list, 'Singapore')
spi_df_final <- spi_df_final %>%
  arrange(country, date) %>%
  group_by(country) %>%
  mutate(across(starts_with("SPI"), na.locf, na.rm=FALSE)) %>%
  mutate(across(c("SPI.D2.1.GDDS","SPI.D2.4.NADA","SPI.D4.1.1.POPU","SPI.D4.1.2.AGRI","SPI.D4.1.3.BIZZ","SPI.D4.1.4.HOUS","SPI.D4.1.5.AGSVY",
                  "SPI.D4.1.6.LABR","SPI.D4.1.7.HLTH","SPI.D4.1.8.BZSVY",
                  "SPI.D5.1.DILG",
                  "SPI.D5.2.1.SNAU", "SPI.D5.2.2.NABY", "SPI.D5.2.1.SNAU","SPI.D5.2.2.NABY",                
                  "SPI.D5.2.3.CNIN", "SPI.D5.2.4.CPIBY", "SPI.D5.2.5.HOUS", "SPI.D5.2.6.EMPL","SPI.D5.2.7.CGOV", "SPI.D5.2.8.FINA",
                  "SPI.D5.2.9.MONY", "SPI.D5.2.10.GSBP",
                  "SPI.D5.5.DIFI"),
                ~if_else(( (income=='High income') & (country %in% country_mod_list)),1,.)                )) 
#write to csv
spi_df_final %>%
  mutate(across(is.list, as.character)) %>%
  write_excel_csv( path = paste(output_dir, 'SPI_data.csv', sep="/"))

#label data
#read in metadata
names_df <- data.frame('source_id'=colnames(spi_df_final))

spi_meta <- read_csv(paste(raw_dir, '/metadata/SPI_dimensions_sources.csv', sep="")) %>%
  right_join(names_df) %>%
  mutate(source_name=if_else(is.na(source_name), paste(source_id), source_name)) %>%
  arrange(factor(source_id, levels=colnames(spi_df_final)))

#label data

label(spi_df_final) = as.list(spi_meta$source_name)


#write to stata
spi_df_final %>%
  mutate(across(is.list, as.character)) %>%
  rename_with(~gsub(".","_",.x, fixed=TRUE)) %>%
  select(-lat,-long) %>%
  write_dta( path = paste(output_dir, 'SPI_data.dta', sep="/"))

Annex

Overall Index Score

For research purposes, we create an index combining several of the indicators together to get an overview of country performance.

The Index will contain only a subset of the dimensions from our framework. For dimensions excluded, we either lacked a source with a developed methodology or else the data collection for that measure was incomplete. The sub-dimensions excluded from our index includes:

  • Indicator 1.1: Data use by national legislature
  • Indicator 1.2: Data use by national executive branch
  • Indicator 1.3: Data use by civil society
  • Indicator 1.4: Data use by academia
  • Indicator 1.5: Data use by international organizations
  • Indicator 2.3: Advisory/ Analytical Services
  • Indicator 4.4: private/citizen generated data
  • Indicator 5.1: legislation and governance
  • Indicator 5.3: skills
  • Indicator 5.4: partnerships
  • Indicator 5.5: finance

Also the Social Protection administrative data and Labor administrative data components are removed from the subsection on administrative data, because of gaps in reporting of sources across countries and over time.

# create index dataset
spi_index_df_temp <- spi_df %>%
  select(country, iso3c, date, starts_with("SPI"), income, region) %>%
  right_join(spi_df_empty) %>%
  left_join(pop_df) %>%
  arrange(-date,country)

#Drop certain indicators that don't make cut because of imcomplete coverage usually
spi_index_df_temp <- spi_index_df_temp %>%
  select(-starts_with('SPI.D1'), -SPI.D5.3.DISK, -SPI.D4.3.GEO.second.admin.level,, -SPI.D4.2.1.SPL, -SPI.D4.2.4.LBR) 





#first index 
# just take a simple numeric average acorss all indicators
# I will forward fill all indicators if they are missing
spi_index_simple <- spi_index_df_temp %>%
  arrange(country, date) %>%
  group_by(country) %>%
  mutate(across(starts_with("SPI"), na.locf, na.rm=FALSE)) %>%
  mutate(across(c("SPI.D2.1.GDDS","SPI.D2.4.NADA","SPI.D4.1.1.POPU","SPI.D4.1.2.AGRI","SPI.D4.1.3.BIZZ","SPI.D4.1.4.HOUS","SPI.D4.1.5.AGSVY",
                  "SPI.D4.1.6.LABR","SPI.D4.1.7.HLTH","SPI.D4.1.8.BZSVY",
                  "SPI.D5.2.1.SNAU", "SPI.D5.2.2.NABY", "SPI.D5.2.1.SNAU","SPI.D5.2.2.NABY",                
                  "SPI.D5.2.3.CNIN", "SPI.D5.2.4.CPIBY", "SPI.D5.2.5.HOUS", "SPI.D5.2.6.EMPL","SPI.D5.2.7.CGOV", "SPI.D5.2.8.FINA",
                  "SPI.D5.2.9.MONY", "SPI.D5.2.10.GSBP" ),
                ~if_else(( (income=='High income') & (country %in% country_mod_list)),1,.)                )) %>% 
  mutate(SPI.INDEX=rowMeans(across(starts_with("SPI")), na.rm=FALSE),
         SPI.INDEX.DIM2=rowMeans(across(starts_with("SPI.D2")), na.rm=FALSE),
         SPI.INDEX.DIM3=rowMeans(across(starts_with("SPI.D3")), na.rm=FALSE),
         SPI.INDEX.DIM4=rowMeans(across(starts_with("SPI.D4")), na.rm=FALSE),
         SPI.INDEX.DIM5=rowMeans(across(starts_with("SPI.D5")), na.rm=FALSE)
         ) %>% #
  arrange(-date, -SPI.INDEX) %>%
  select(country, iso3c, date, starts_with('SPI.INDEX'), everything())


#################
# Nested Index
################
  spi_index_df <- spi_index_df_temp %>%
  arrange(country, date) %>%
  group_by(country) %>%
  mutate(across(starts_with("SPI"), na.locf, na.rm=FALSE)) %>%
  mutate(across(c("SPI.D2.1.GDDS","SPI.D2.4.NADA","SPI.D4.1.1.POPU","SPI.D4.1.2.AGRI","SPI.D4.1.3.BIZZ","SPI.D4.1.4.HOUS","SPI.D4.1.5.AGSVY",
                  "SPI.D4.1.6.LABR","SPI.D4.1.7.HLTH","SPI.D4.1.8.BZSVY",
                  "SPI.D5.2.1.SNAU", "SPI.D5.2.2.NABY", "SPI.D5.2.1.SNAU","SPI.D5.2.2.NABY",                
                  "SPI.D5.2.3.CNIN", "SPI.D5.2.4.CPIBY", "SPI.D5.2.5.HOUS", "SPI.D5.2.6.EMPL","SPI.D5.2.7.CGOV", "SPI.D5.2.8.FINA",
                  "SPI.D5.2.9.MONY", "SPI.D5.2.10.GSBP" ),
                ~if_else(( (income=='High income') & (country %in% country_mod_list)),1,.)                )) %>% 
  mutate(SPI.INDEX=rowMeans(across(starts_with("SPI")), na.rm=FALSE),
         SPI.INDEX.DIM2=rowMeans(across(starts_with("SPI.D2")), na.rm=FALSE),
         SPI.INDEX.DIM3=rowMeans(across(starts_with("SPI.D3")), na.rm=FALSE),
         SPI.INDEX.DIM4=rowMeans(across(starts_with("SPI.D4")), na.rm=FALSE),
         SPI.INDEX.DIM5=rowMeans(across(starts_with("SPI.D5")), na.rm=FALSE)
         ) %>% #
  arrange(-date, -SPI.INDEX) %>%
  select(country, iso3c, date, starts_with('SPI.INDEX'), everything())



#Create overall subscores corresponding to John's framework
  spi_index_df <- spi_index_df %>%
    mutate(INDEX.SPI.D2.1=rowMeans(across(starts_with('SPI.D2.1'))),
         INDEX.SPI.D2.2=SPI.D2.2.Openness.subscore,
         INDEX.SPI.D2.4=SPI.D2.4.NADA,
         INDEX.SPI.D3.1=rowMeans(across(c("SPI.D3.1.POV",
                                            "SPI.D3.2.HNGR",
                                            "SPI.D3.3.HLTH",
                                            "SPI.D3.4.EDUC",
                                            "SPI.D3.5.GEND",
                                            "SPI.D3.6.WTRS"))),
         INDEX.SPI.D3.2=rowMeans(across(c("SPI.D3.7.ENRG",
                                            "SPI.D3.8.WORK",
                                            "SPI.D3.9.INDY",
                                            "SPI.D3.10.NEQL",
                                            "SPI.D3.11.CITY",
                                            "SPI.D3.12.CNSP"))),         
         INDEX.SPI.D3.3=rowMeans(across(c("SPI.D3.13.CLMT",
                                            "SPI.D3.15.LAND" ))),
         INDEX.SPI.D3.4=rowMeans(across(c("SPI.D3.16.INST",
                                            "SPI.D3.17.PTNS" ))),
         INDEX.SPI.D4.1=rowMeans(across(starts_with('SPI.D4.1'))),
         INDEX.SPI.D4.2=rowMeans(across(starts_with('SPI.D4.2'))),
         INDEX.SPI.D4.3=rowMeans(across(starts_with('SPI.D4.3'))),
         #INDEX.SPI.D5.1=rowMeans(across(starts_with('SPI.D5.1'))),
         INDEX.SPI.D5.2=rowMeans(across(starts_with('SPI.D5.2'))),
         #INDEX.SPI.D5.5=rowMeans(across(starts_with('SPI.D5.5')))
                 ) %>%
  mutate(SPI.INDEX=rowMeans(across(starts_with("INDEX.SPI")), na.rm=FALSE),
         SPI.INDEX.DIM2=rowMeans(across(starts_with("INDEX.SPI.D2")), na.rm=FALSE),
         SPI.INDEX.DIM3=rowMeans(across(starts_with("INDEX.SPI.D3")), na.rm=FALSE),
         SPI.INDEX.DIM4=rowMeans(across(starts_with("INDEX.SPI.D4")), na.rm=FALSE),
         SPI.INDEX.DIM5=rowMeans(across(starts_with("INDEX.SPI.D5")), na.rm=FALSE)
         ) %>% #
  arrange(-date, -SPI.INDEX) %>%
  select(country, iso3c, date, starts_with('SPI.INDEX'), everything())

spi_mapper('spi_index_df','SPI.INDEX','Overall SPI  Index Averaging Over All Sub-Dimensions.  Equal Weight for Each Sub-Dimension.')

#display top 25
index_disp <- spi_index_df %>%
  ungroup() %>%
  filter(date==2019) %>%
  arrange(-SPI.INDEX) %>%
  mutate(across(starts_with('SPI.INDEX'),~100*.),
         across(starts_with('SPI.INDEX'),round,1)) %>%
  select(country, iso3c, date, starts_with('SPI.INDEX'))

DT::datatable(index_disp, caption='Overall SPI  Index Averaging Over All Sub-Dimensions.  Equal Weight for Each Sub-Dimension.',
                      rownames=TRUE,
                      colnames = c("Country", "ISO3C", "Date", "SPI Index Value",
                                   "Dimension 2: Data Services",
                                   "Dimension 3: Data Products ",
                                   "Dimension 4: Data Sources",
                                   "Dimension 5: Data Infrastructure"
                                   ),
                      class='cell-border stripe',
                      escape = FALSE,
                      extensions = c ('Buttons', 'FixedHeader'), options=list(
                          dom = 'Bfrtip',
                          buttons = c('copy', 'csv', 'excel'),
                          pageLength = 25,
                          scrollX = TRUE, 
                          paging=FALSE,
                          ordering=F)) 

## [1] 0.7368959
## [1] 0.8492594